package com.lingyue.parse.service;

import com.lingyue.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * Excel表格文本提取服务
 * 支持.xlsx和.xls格式
 * 
 * @author lingyue
 * @since 2026-01-14
 */
@Slf4j
@Service
public class ExcelTextExtractionService {
    
    /**
     * 提取Excel表格文本
     * 
     * @param excelFilePath Excel文件路径
     * @return 提取的文本内容（表格格式）
     */
    public String extractText(String excelFilePath) {
        File excelFile = new File(excelFilePath);
        if (!excelFile.exists()) {
            throw new ServiceException("Excel文件不存在: " + excelFilePath);
        }
        
        String fileName = excelFile.getName().toLowerCase();
        
        try {
            if (fileName.endsWith(".xlsx")) {
                return extractFromXlsx(excelFilePath);
            } else if (fileName.endsWith(".xls")) {
                return extractFromXls(excelFilePath);
            } else {
                throw new ServiceException("不支持的Excel文件格式: " + fileName);
            }
        } catch (IOException e) {
            log.error("提取Excel表格文本失败: {}", excelFilePath, e);
            throw new ServiceException("提取Excel表格文本失败: " + e.getMessage());
        }
    }
    
    /**
     * 从.xlsx文件提取文本
     */
    private String extractFromXlsx(String filePath) throws IOException {
        log.info("提取.xlsx文件文本: {}", filePath);
        
        StringBuilder text = new StringBuilder();
        
        try (FileInputStream fis = new FileInputStream(filePath);
             Workbook workbook = new XSSFWorkbook(fis)) {
            
            int sheetCount = workbook.getNumberOfSheets();
            log.debug("Excel文件包含 {} 个工作表", sheetCount);
            
            for (int sheetIndex = 0; sheetIndex < sheetCount; sheetIndex++) {
                Sheet sheet = workbook.getSheetAt(sheetIndex);
                String sheetName = sheet.getSheetName();
                
                text.append("=== 工作表: ").append(sheetName).append(" ===\n");
                
                // 遍历所有行
                for (Row row : sheet) {
                    StringBuilder rowText = new StringBuilder();
                    
                    // 遍历所有单元格
                    for (Cell cell : row) {
                        String cellValue = getCellValueAsString(cell);
                        rowText.append(cellValue).append("\t");
                    }
                    
                    if (rowText.length() > 0) {
                        text.append(rowText.toString().trim()).append("\n");
                    }
                }
                
                text.append("\n");
            }
        }
        
        String result = text.toString();
        log.debug("提取到文本长度: {}", result.length());
        return result;
    }
    
    /**
     * 从.xls文件提取文本
     */
    private String extractFromXls(String filePath) throws IOException {
        log.info("提取.xls文件文本: {}", filePath);
        
        StringBuilder text = new StringBuilder();
        
        try (FileInputStream fis = new FileInputStream(filePath);
             Workbook workbook = new HSSFWorkbook(fis)) {
            
            int sheetCount = workbook.getNumberOfSheets();
            log.debug("Excel文件包含 {} 个工作表", sheetCount);
            
            for (int sheetIndex = 0; sheetIndex < sheetCount; sheetIndex++) {
                Sheet sheet = workbook.getSheetAt(sheetIndex);
                String sheetName = sheet.getSheetName();
                
                text.append("=== 工作表: ").append(sheetName).append(" ===\n");
                
                // 遍历所有行
                for (Row row : sheet) {
                    StringBuilder rowText = new StringBuilder();
                    
                    // 遍历所有单元格
                    for (Cell cell : row) {
                        String cellValue = getCellValueAsString(cell);
                        rowText.append(cellValue).append("\t");
                    }
                    
                    if (rowText.length() > 0) {
                        text.append(rowText.toString().trim()).append("\n");
                    }
                }
                
                text.append("\n");
            }
        }
        
        String result = text.toString();
        log.debug("提取到文本长度: {}", result.length());
        return result;
    }
    
    /**
     * 获取单元格值（字符串格式）
     */
    private String getCellValueAsString(Cell cell) {
        if (cell == null) {
            return "";
        }
        
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    // 日期格式
                    return cell.getDateCellValue().toString();
                } else {
                    // 数字格式，避免科学计数法
                    double numericValue = cell.getNumericCellValue();
                    if (numericValue == (long) numericValue) {
                        return String.valueOf((long) numericValue);
                    } else {
                        return String.valueOf(numericValue);
                    }
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                // 公式单元格，获取计算结果
                try {
                    if (cell.getCachedFormulaResultType() == CellType.NUMERIC) {
                        double numericValue = cell.getNumericCellValue();
                        if (numericValue == (long) numericValue) {
                            return String.valueOf((long) numericValue);
                        } else {
                            return String.valueOf(numericValue);
                        }
                    } else if (cell.getCachedFormulaResultType() == CellType.STRING) {
                        return cell.getStringCellValue();
                    } else if (cell.getCachedFormulaResultType() == CellType.BOOLEAN) {
                        return String.valueOf(cell.getBooleanCellValue());
                    }
                } catch (Exception e) {
                    log.debug("获取公式计算结果失败，返回公式字符串", e);
                    return cell.getCellFormula();
                }
                return cell.getCellFormula();
            case BLANK:
                return "";
            default:
                return "";
        }
    }
}
