package com.ruoyi.web.calculate.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.web.calculate.domain.CmcDegreeToRadian;
import com.ruoyi.web.calculate.service.ICmcDegreeToRadianService;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

/**
 * 角度度转弧度服务实现
 * 
 * @author ruoyi
 * @date 2026-06-17
 */
@Service
public class CmcDegreeToRadianServiceImpl implements ICmcDegreeToRadianService {

    /**
     * 导入Excel数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult importExcelData(MultipartFile file) {
        try {
            // 获取Excel表头信息
            List<String> excelColumns = getExcelColumns(file);

            // 返回原始Excel数据格式（使用表头作为key）
            List<Map<String, Object>> rawData = readRawExcelData(file, excelColumns);

            // 检查是否有数据
            if (rawData == null || rawData.isEmpty()) {
                return AjaxResult.error("Excel文件中没有数据！");
            }

            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("total", rawData.size());
            result.put("validCount", rawData.size());
            result.put("data", rawData);
            result.put("columns", excelColumns); // 返回Excel表头

            String message = String.format("导入成功！共解析%d条数据", rawData.size());
            return AjaxResult.success(message, result);

        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("导入失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取Excel表头信息
     */
    private List<String> getExcelColumns(MultipartFile file) {
        List<String> columns = new ArrayList<>();
        try {
            Workbook workbook = WorkbookFactory.create(file.getInputStream());
            Sheet sheet = workbook.getSheetAt(0);
            Row headerRow = sheet.getRow(0); // 第一行为表头
            
            if (headerRow != null) {
                int lastCellNum = headerRow.getLastCellNum();
                for (int i = 0; i < lastCellNum; i++) {
                    Cell cell = headerRow.getCell(i);
                    String cellValue = null;
                    if (cell != null) {
                        cellValue = getCellStringValue(cell);
                    }
                    if (cellValue != null && !cellValue.trim().isEmpty()) {
                        columns.add(cellValue.trim());
                    } else {
                        columns.add("列" + (i + 1));
                    }
                }
            }
            workbook.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return columns;
    }
    
    /**
     * 获取单元格的字符串值（处理多种类型）
     */
    private String getCellStringValue(Cell cell) {
        if (cell == null) {
            return null;
        }
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getLocalDateTimeCellValue().toString();
                } else {
                    double value = cell.getNumericCellValue();
                    if (value == Math.floor(value)) {
                        return String.valueOf((long) value);
                    }
                    return String.valueOf(value);
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                try {
                    return cell.getStringCellValue();
                } catch (Exception e) {
                    try {
                        return String.valueOf(cell.getNumericCellValue());
                    } catch (Exception ex) {
                        return cell.getCellFormula();
                    }
                }
            default:
                return null;
        }
    }
    
    /**
     * 读取原始Excel数据（使用表头作为key）
     */
    private List<Map<String, Object>> readRawExcelData(MultipartFile file, List<String> columns) {
        List<Map<String, Object>> dataList = new ArrayList<>();
        try {
            Workbook workbook = WorkbookFactory.create(file.getInputStream());
            Sheet sheet = workbook.getSheetAt(0);
            int rows = sheet.getLastRowNum();
            
            // 从第二行开始读取数据（第一行为表头）
            for (int i = 1; i <= rows; i++) {
                Row row = sheet.getRow(i);
                if (row == null || isRowEmpty(row)) {
                    continue;
                }
                
                Map<String, Object> rowMap = new HashMap<>();
                int lastCellNum = Math.min(row.getLastCellNum(), columns.size());
                for (int j = 0; j < lastCellNum; j++) {
                    Cell cell = row.getCell(j);
                    Object value = getCellValue(cell);
                    rowMap.put(columns.get(j), value);
                }
                dataList.add(rowMap);
            }
            workbook.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dataList;
    }
    
    /**
     * 判断行是否为空
     */
    private boolean isRowEmpty(Row row) {
        if (row == null) {
            return true;
        }
        for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
            Cell cell = row.getCell(i);
            if (cell != null && cell.getCellType() != CellType.BLANK) {
                // 使用getCellValue方法处理多种类型，避免数字类型调用getStringCellValue抛出异常
                Object value = getCellValue(cell);
                if (value != null) {
                    String strValue = String.valueOf(value).trim();
                    if (!strValue.isEmpty()) {
                        return false;
                    }
                }
            }
        }
        return true;
    }
    
    /**
     * 获取单元格值
     */
    private Object getCellValue(Cell cell) {
        if (cell == null) {
            return null;
        }
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getLocalDateTimeCellValue();
                } else {
                    // 避免科学计数法
                    double value = cell.getNumericCellValue();
                    if (value == Math.floor(value)) {
                        return (long) value;
                    }
                    return value;
                }
            case BOOLEAN:
                return cell.getBooleanCellValue();
            case FORMULA:
                try {
                    return cell.getStringCellValue();
                } catch (Exception e) {
                    return cell.getNumericCellValue();
                }
            default:
                return null;
        }
    }

    /**
     * 执行角度度转弧度计算
     */
    @Override
    public List<CmcDegreeToRadian> calculateDegreeToRadian(List<CmcDegreeToRadian> dataList) {
        List<CmcDegreeToRadian> resultList = new ArrayList<>();
        for (CmcDegreeToRadian item : dataList) {
            try {
                CmcDegreeToRadian result = calculateDegreeToRadianSingle(item);
                resultList.add(result);
            } catch (Exception e) {
                e.printStackTrace();
                // 计算失败时，返回带有错误信息的对象
                CmcDegreeToRadian errorResult = new CmcDegreeToRadian();
                errorResult.setPointNumber(item.getPointNumber());
                errorResult.setLongitudeRadian(-1.0);
                errorResult.setLatitudeRadian(-1.0);
                resultList.add(errorResult);
            }
        }

        return resultList;
    }

    /**
     * 单条角度度转弧度计算（待实现）
     */
    private CmcDegreeToRadian calculateDegreeToRadianSingle(CmcDegreeToRadian cmcDegreeToRadian) {
        double longitude = cmcDegreeToRadian.getLongitude();
        double latitude = cmcDegreeToRadian.getLatitude();

        // 转换为弧度
        double longitudeRadian = Math.toRadians(longitude);
        double latitudeRadian = Math.toRadians(latitude);
        
        cmcDegreeToRadian.setLongitudeRadian(longitudeRadian);
        cmcDegreeToRadian.setLatitudeRadian(latitudeRadian);

        return cmcDegreeToRadian;
    }
}
