#include "ExcelReader.h"
#include <iostream>
#include <stdexcept>

// 构造函数：初始化文件路径和文件类型
ExcelReader::ExcelReader(const std::string& fileName) : fileName(fileName), isXlsx(false) {
    // 判断文件类型（.xls 或 .xlsx）
    if (fileName.substr(fileName.find_last_of(".") + 1) == "xlsx") {
      // 如果是.xlsx文件，标记为XLSX文件
        isXlsx = true;  
      
      // 加载.xlsx文件
        loadFile();  
    } else if (fileName.substr(fileName.find_last_of(".") + 1) == "xls") {
      // 如果是.xls文件，标记为XLS文件
        isXlsx = false;  
      
      // 读取.xls文件
        readXlsFile();  
    } else {
         // 如果不是支持的文件类型，抛出异常
        throw std::invalid_argument("Unsupported file type!"); 
    }
}

// 加载 .xlsx 文件
void ExcelReader::loadFile() {
    try {
        // 加载 Excel 文件
        workbook.load(fileName);  
    } catch (const std::exception& e) {
        // 捕获异常并打印错误信息
        std::cerr << "Error loading file: " << e.what() << std::endl;  
      
      // 抛出异常
        throw;  
    }
}

// 读取 .xls 文件
void ExcelReader::readXlsFile() {
    // 使用 libxls 库读取 .xls 文件
    xlsWorkBook* pWB = xls_open(fileName.c_str(), "UTF-8");
    if (!pWB) {
      // 如果文件打开失败，打印错误信息
        std::cerr << "Failed to open .xls file." << std::endl;  
       // 抛出异常
        throw std::runtime_error("Failed to open .xls file."); 
    }
  
   // 假设文件处理完毕，关闭文件
    xls_close(pWB); 
  // 提示.xls文件读取尚未完全支持
    std::cerr << "Reading .xls file not yet supported in detail." << std::endl;  
}

// 获取所有工作表的名称
std::vector<std::string> ExcelReader::getSheetNames() const {
  
  // 定义存储工作表名称的向量
    std::vector<std::string> sheetNames;  
    if (isXlsx) {
      // 遍历所有工作表名称
        for (const auto& sheet : workbook.sheet_names()) {  
           // 将工作表名称添加到返回的向量中
            sheetNames.push_back(sheet); 
        }
    }

    // 返回所有工作表名称
    return sheetNames;  
}

// 读取指定工作表的数据
std::vector<std::vector<std::string>> ExcelReader::readSheetData(const std::string& sheetName) {
  // 定义存储工作表数据的二维向量
    std::vector<std::vector<std::string>> data;  
    if (isXlsx) {
        try {
          
         // 获取指定名称的工作表
            auto worksheet = workbook.sheet_by_title(sheetName);  
          // 遍历工作表的每一行
            for (auto row : worksheet.rows()) {  
              // 定义存储每行数据的向量
                std::vector<std::string> rowData;  
              // 遍历行中的每个单元格
                for (auto cell : row) {  
                   // 将单元格的值添加到当前行数据中
                    rowData.push_back(cell.to_string()); 
                }
              // 将当前行数据添加到二维向量中
                data.push_back(rowData);  
            }
        } catch (const std::exception& e) {
          // 捕获异常并打印错误信息
            std::cerr << "Error reading sheet " << sheetName << ": " << e.what() << std::endl;  
          // 抛出异常
            throw;  
        }
    }
   // 返回工作表的数据
    return data; 
}

// 获取指定单元格的数据类型
std::string ExcelReader::getCellDataType(const std::string& sheetName, int row, int col) {
  // 默认数据类型为"Unknown"
    std::string result = "Unknown";  
    if (isXlsx) {
        try {
          // 获取指定名称的工作表
            auto worksheet = workbook.sheet_by_title(sheetName);  
          // 获取指定单元格
            auto cell = worksheet.cell(xlnt::cell_reference(col, row));  
            if (cell.is_string()) {
               // 如果单元格是字符串类型
                result = "String"; 
            } else if (cell.is_number()) {
               // 如果单元格是数字类型
                result = "Number"; 
            } else if (cell.is_date()) {
               // 如果单元格是日期类型
                result = "Date"; 
            }
        } catch (const std::exception& e) {
          
          // 捕获异常并打印错误信息
            std::cerr << "Error reading cell (" << row << ", " << col << "): " << e.what() << std::endl;  
          // 返回"Error"表示读取单元格出错
            result = "Error";  
        }
    }
  // 返回数据类型
    return result;  
}

// 写入指定单元格的数据
void ExcelReader::writeCellData(const std::string& sheetName, int row, int col, const std::string& value) {
    if (isXlsx) {
        try {
           // 获取指定名称的工作表
            auto worksheet = workbook.sheet_by_title(sheetName); 
           // 写入单元格的数据
            worksheet.cell(xlnt::cell_reference(col, row)).value(value); 
        } catch (const std::exception& e) {
          
          // 捕获异常并打印错误信息
            std::cerr << "Error writing to cell (" << row << ", " << col << "): " << e.what() << std::endl;  
        }
    }
}

// 保存Excel文件
void ExcelReader::saveToFile(const std::string& newFileName) {
    if (isXlsx) {
        try {
          // 保存文件
            workbook.save(newFileName);  
        } catch (const std::exception& e) {
          
          // 捕获异常并打印错误信息
            std::cerr << "Error saving to file: " << e.what() << std::endl;  
        }
    }
}

// 设置数字格式
void ExcelReader::setCellNumberFormat(const std::string& sheetName, int row, int col, const std::string& format) {
    if (isXlsx) {
        try {
          // 获取指定名称的工作表
            auto worksheet = workbook.sheet_by_title(sheetName);  
          // 获取指定单元格
            auto cell = worksheet.cell(xlnt::cell_reference(col, row));  
            xlnt::style style;
           // 设置单元格数字格式
            style.number_format(format); 
          // 应用样式
            cell.style(style);  
        } catch (const std::exception& e) {
          
          // 捕获异常并打印错误信息
            std::cerr << "Error setting number format for cell (" << row << ", " << col << "): " << e.what() << std::endl;  
        }
    }
}

// 合并单元格
void ExcelReader::mergeCells(const std::string& sheetName, int startRow, int startCol, int endRow, int endCol) {
    if (isXlsx) {
        try {
          // 获取指定名称的工作表
            auto worksheet = workbook.sheet_by_title(sheetName);  
          // 合并单元格
            worksheet.merge_cells(xlnt::cell_range(xlnt::cell_reference(startCol, startRow),
                                                  xlnt::cell_reference(endCol, endRow)));  
        } catch (const std::exception& e) {
          
           // 捕获异常并打印错误信息
            std::cerr << "Error merging cells: " << e.what() << std::endl; 
        }
    }
}
