package com.ruoyi.system.service.impl;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.FloodCase;
import com.ruoyi.system.mapper.FloodCaseMapper;
import com.ruoyi.system.service.IFloodCaseService;

/**
 * 洪水案例库Service业务层处理
 *
 * @author jackeyhuang
 * @version 1.0.0
 * @date 2025-01-27
 */
@Service
public class FloodCaseServiceImpl implements IFloodCaseService
{
    private static final Logger log = LoggerFactory.getLogger(FloodCaseServiceImpl.class);

    @Autowired
    private FloodCaseMapper floodCaseMapper;

    /**
     * 查询洪水案例库
     *
     * @param caseId 洪水案例库主键
     * @return 洪水案例库
     */
    @Override
    public FloodCase selectFloodCaseByCaseId(Long caseId)
    {
        return floodCaseMapper.selectFloodCaseByCaseId(caseId);
    }

    /**
     * 查询洪水案例库列表
     *
     * @param floodCase 洪水案例库
     * @return 洪水案例库
     */
    @Override
    public List<FloodCase> selectFloodCaseList(FloodCase floodCase)
    {
        return floodCaseMapper.selectFloodCaseList(floodCase);
    }

    /**
     * 新增洪水案例库
     *
     * @param floodCase 洪水案例库
     * @return 结果
     */
    @Override
    public int insertFloodCase(FloodCase floodCase)
    {
        if (StringUtils.isEmpty(floodCase.getStatus()))
        {
            floodCase.setStatus("0");
        }
        return floodCaseMapper.insertFloodCase(floodCase);
    }

    /**
     * 修改洪水案例库
     *
     * @param floodCase 洪水案例库
     * @return 结果
     */
    @Override
    public int updateFloodCase(FloodCase floodCase)
    {
        return floodCaseMapper.updateFloodCase(floodCase);
    }

    /**
     * 批量删除洪水案例库
     *
     * @param caseIds 需要删除的洪水案例库主键
     * @return 结果
     */
    @Override
    public int deleteFloodCaseByCaseIds(Long[] caseIds)
    {
        return floodCaseMapper.deleteFloodCaseByCaseIds(caseIds);
    }

    /**
     * 删除洪水案例库信息
     *
     * @param caseId 洪水案例库主键
     * @return 结果
     */
    @Override
    public int deleteFloodCaseByCaseId(Long caseId)
    {
        return floodCaseMapper.deleteFloodCaseByCaseId(caseId);
    }

    /**
     * 导入洪水案例数据
     *
     * @param file 上传的文件
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName 操作用户
     * @return 结果
     */
    @Override
    public String importFloodCase(MultipartFile file, Boolean isUpdateSupport, String operName)
    {
        if (file == null || file.isEmpty())
        {
            throw new ServiceException("导入文件不能为空！");
        }
        
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        
        try (InputStream is = file.getInputStream())
        {
            Workbook workbook = WorkbookFactory.create(is);
            
            // 遍历所有sheet，每个sheet作为一个案例类型
            for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++)
            {
                Sheet sheet = workbook.getSheetAt(sheetIndex);
                String caseType = sheet.getSheetName(); // sheet名称作为案例类型
                
                if (sheet.getLastRowNum() < 1)
                {
                    continue; // 跳过空sheet
                }
                
                // 读取表头，获取列名
                Row headerRow = sheet.getRow(0);
                if (headerRow == null)
                {
                    continue;
                }
                
                Map<Integer, String> columnMap = new HashMap<>();
                for (int col = 0; col < headerRow.getLastCellNum(); col++)
                {
                    Cell cell = headerRow.getCell(col);
                    if (cell != null)
                    {
                        String columnName = cell.toString().trim();
                        if (StringUtils.isNotEmpty(columnName))
                        {
                            columnMap.put(col, columnName);
                        }
                    }
                }
                
                // 从第二行开始读取数据
                for (int i = 1; i <= sheet.getLastRowNum(); i++)
                {
                    Row row = sheet.getRow(i);
                    if (row == null)
                    {
                        continue;
                    }
                    
                    try
                    {
                        FloodCase floodCase = new FloodCase();
                        floodCase.setCaseType(caseType);
                        
                        // 读取所有列的数据
                        Map<String, Object> caseDataMap = new HashMap<>();
                        String caseName = "";
                        String caseTime = "";
                        String caseLocation = "";
                        String caseDescription = "";
                        
                        for (Map.Entry<Integer, String> entry : columnMap.entrySet())
                        {
                            int colIndex = entry.getKey();
                            String columnName = entry.getValue();
                            String cellValue = getCellValue(row, colIndex);
                            
                            if (StringUtils.isEmpty(cellValue))
                            {
                                continue;
                            }
                            
                            // 智能匹配列名到字段（支持多种列名变体）
                            String normalizedColumnName = columnName.trim();
                            
                            // 核心字段匹配（根据实际Excel列名）
                            // 注意：需要精确匹配，避免"持续时间"被误匹配为"时间"
                            if (normalizedColumnName.contains("灾害案例") || normalizedColumnName.contains("案例") || 
                                normalizedColumnName.contains("名称") || normalizedColumnName.equals("灾害案例") ||
                                normalizedColumnName.equals("案例名称") || normalizedColumnName.equals("名称"))
                            {
                                caseName = cellValue;
                            }
                            // 优先精确匹配"持续时间"列（必须在"时间"之前，避免"持续时间"被误匹配为"时间"）
                            else if (normalizedColumnName.equals("持续时间") || normalizedColumnName.contains("持续时间"))
                            {
                                floodCase.setDuration(cellValue);
                            }
                            // 精确匹配"时间"列（案例时间）
                            else if (normalizedColumnName.equals("时间") || normalizedColumnName.equals("案例时间") ||
                                     normalizedColumnName.equals("发生时间") || normalizedColumnName.equals("日期"))
                            {
                                caseTime = cellValue;
                            }
                            else if (normalizedColumnName.contains("地点") || normalizedColumnName.contains("位置") || 
                                     normalizedColumnName.contains("地区") || normalizedColumnName.contains("发生地点") ||
                                     normalizedColumnName.contains("区域") || normalizedColumnName.equals("地点"))
                            {
                                caseLocation = cellValue;
                            }
                            else if (normalizedColumnName.contains("原因") || normalizedColumnName.equals("原因"))
                            {
                                // "原因"列映射到洪水成因
                                floodCase.setFloodCause(cellValue);
                            }
                            else if (normalizedColumnName.contains("流量") || normalizedColumnName.contains("降雨") ||
                                     normalizedColumnName.contains("流量、降雨") || normalizedColumnName.equals("流量、降雨"))
                            {
                                // "流量、降雨"列包含洪峰流量和降雨量信息
                                // 尝试提取洪峰流量和降雨量
                                String flowValue = extractFlowValue(cellValue);
                                String rainValue = extractRainValue(cellValue);
                                if (StringUtils.isNotEmpty(flowValue))
                                {
                                    floodCase.setPeakFlow(flowValue);
                                }
                                if (StringUtils.isNotEmpty(rainValue))
                                {
                                    floodCase.setRainfall(rainValue);
                                }
                                // 如果无法分离，全部存入peakFlow
                                if (StringUtils.isEmpty(flowValue) && StringUtils.isEmpty(rainValue))
                                {
                                    floodCase.setPeakFlow(cellValue);
                                }
                            }
                            else if (normalizedColumnName.contains("损失") || normalizedColumnName.equals("损失"))
                            {
                                // "损失"列包含经济损失、人员伤亡等信息
                                floodCase.setEconomicLoss(cellValue);
                                // 尝试提取人员伤亡信息
                                if (cellValue.contains("伤亡") || cellValue.contains("死亡") || cellValue.contains("受伤"))
                                {
                                    floodCase.setCasualties(extractCasualties(cellValue));
                                }
                            }
                            else if (normalizedColumnName.contains("洪水过程") || normalizedColumnName.equals("洪水过程"))
                            {
                                // "洪水过程"列映射到案例描述或洪水过程描述
                                if (StringUtils.isEmpty(caseDescription))
                                {
                                    caseDescription = cellValue;
                                }
                                else
                                {
                                    caseDescription += "\n\n洪水过程：\n" + cellValue;
                                }
                            }
                            else if (normalizedColumnName.contains("其他") || normalizedColumnName.equals("其他"))
                            {
                                // "其他"列存入caseData
                                caseDataMap.put("其他", cellValue);
                            }
                            else if (normalizedColumnName.contains("描述") || normalizedColumnName.contains("说明") || 
                                     normalizedColumnName.contains("简介") || normalizedColumnName.contains("概述"))
                            {
                                caseDescription = cellValue;
                            }
                            // 扩展字段匹配
                            else if (normalizedColumnName.contains("灾害类型") || normalizedColumnName.contains("类型"))
                            {
                                floodCase.setDisasterType(cellValue);
                            }
                            else if (normalizedColumnName.contains("影响范围") || normalizedColumnName.contains("受灾区域") ||
                                     normalizedColumnName.contains("范围") || normalizedColumnName.contains("区域"))
                            {
                                floodCase.setAffectedArea(cellValue);
                            }
                            else if (normalizedColumnName.contains("经济损失") || normalizedColumnName.contains("损失"))
                            {
                                floodCase.setEconomicLoss(cellValue);
                            }
                            else if (normalizedColumnName.contains("人员伤亡") || normalizedColumnName.contains("伤亡"))
                            {
                                floodCase.setCasualties(cellValue);
                            }
                            else if (normalizedColumnName.contains("降雨量") || normalizedColumnName.contains("雨量"))
                            {
                                floodCase.setRainfall(cellValue);
                            }
                            else if (normalizedColumnName.contains("水位"))
                            {
                                floodCase.setWaterLevel(cellValue);
                            }
                            // 持续时间已在上面精确匹配，这里不再重复匹配
                            else if (normalizedColumnName.contains("应对措施") || normalizedColumnName.contains("措施") ||
                                     normalizedColumnName.contains("响应措施"))
                            {
                                floodCase.setResponseMeasures(cellValue);
                            }
                            else if (normalizedColumnName.contains("流域"))
                            {
                                floodCase.setRiverBasin(cellValue);
                            }
                            else if (normalizedColumnName.contains("洪水规模") || normalizedColumnName.contains("规模"))
                            {
                                floodCase.setFloodScale(cellValue);
                            }
                            else if (normalizedColumnName.contains("洪峰流量") || normalizedColumnName.contains("流量"))
                            {
                                floodCase.setPeakFlow(cellValue);
                            }
                            else if (normalizedColumnName.contains("受灾人口") || normalizedColumnName.contains("人口"))
                            {
                                floodCase.setAffectedPopulation(cellValue);
                            }
                            else if (normalizedColumnName.contains("房屋损毁") || normalizedColumnName.contains("房屋"))
                            {
                                floodCase.setDamagedHouses(cellValue);
                            }
                            else if (normalizedColumnName.contains("农作物") || normalizedColumnName.contains("作物"))
                            {
                                floodCase.setDamagedCrops(cellValue);
                            }
                            else if (normalizedColumnName.contains("基础设施") || normalizedColumnName.contains("设施"))
                            {
                                floodCase.setInfrastructureDamage(cellValue);
                            }
                            else if (normalizedColumnName.contains("救援情况") || normalizedColumnName.contains("救援"))
                            {
                                floodCase.setRescueSituation(cellValue);
                            }
                            else if (normalizedColumnName.contains("预防措施") || normalizedColumnName.contains("预防"))
                            {
                                floodCase.setPreventionMeasures(cellValue);
                            }
                            else if (normalizedColumnName.contains("经验教训") || normalizedColumnName.contains("教训"))
                            {
                                floodCase.setLessonsLearned(cellValue);
                            }
                            else if (normalizedColumnName.contains("天气情况") || normalizedColumnName.contains("天气"))
                            {
                                floodCase.setWeatherCondition(cellValue);
                            }
                            else if (normalizedColumnName.contains("洪水成因") || normalizedColumnName.contains("成因"))
                            {
                                floodCase.setFloodCause(cellValue);
                            }
                            else if (normalizedColumnName.contains("预警等级") || normalizedColumnName.contains("预警"))
                            {
                                floodCase.setWarningLevel(cellValue);
                            }
                            else if (normalizedColumnName.contains("转移人数") || normalizedColumnName.contains("转移"))
                            {
                                floodCase.setEvacuationNumber(cellValue);
                            }
                            else if (normalizedColumnName.contains("救援队伍") || normalizedColumnName.contains("队伍"))
                            {
                                floodCase.setRescueTeams(cellValue);
                            }
                            else if (normalizedColumnName.contains("物资支援") || normalizedColumnName.contains("物资"))
                            {
                                floodCase.setMaterialSupport(cellValue);
                            }
                            else if (normalizedColumnName.contains("序号") || normalizedColumnName.equals("序号"))
                            {
                                // 序号列忽略，不存储
                            }
                            else
                            {
                                // 未匹配的列存入caseData（保留所有原始数据，确保数据完整性）
                                caseDataMap.put(columnName, cellValue);
                            }
                        }
                        
                        // 验证：如果案例名称和案例时间都为空，则跳过该行，不导入
                        if (StringUtils.isEmpty(caseName) && StringUtils.isEmpty(caseTime))
                        {
                            failureNum++;
                            failureMsg.append("<br/>Sheet[" + caseType + "] 第" + (i + 1) + "行案例名称和案例时间都为空，跳过导入");
                            continue;
                        }
                        
                        // 如果案例名称为空，尝试生成默认名称（但案例时间不能为空）
                        if (StringUtils.isEmpty(caseName))
                        {
                            // 方式1：使用第一列的值（跳过序号列）
                            if (!columnMap.isEmpty())
                            {
                                // 如果第一列是序号，尝试第二列
                                String firstColName = columnMap.get(0);
                                if (firstColName != null && firstColName.contains("序号"))
                                {
                                    if (columnMap.size() > 1)
                                    {
                                        caseName = getCellValue(row, 1);
                                    }
                                }
                                else
                                {
                                    caseName = getCellValue(row, 0);
                                }
                            }
                            
                            // 方式2：如果第一列为空，尝试使用案例时间+地点组合
                            if (StringUtils.isEmpty(caseName))
                            {
                                if (StringUtils.isNotEmpty(caseTime) && StringUtils.isNotEmpty(caseLocation))
                                {
                                    caseName = caseTime + " " + caseLocation;
                                }
                                else if (StringUtils.isNotEmpty(caseTime))
                                {
                                    caseName = caseTime + " 洪水案例";
                                }
                                else if (StringUtils.isNotEmpty(caseLocation))
                                {
                                    caseName = caseLocation + " 洪水案例";
                                }
                                else
                                {
                                    // 方式3：使用案例类型+行号作为默认名称
                                    caseName = caseType + "案例_" + (i + 1);
                                }
                            }
                        }
                        
                        floodCase.setCaseName(caseName);
                        floodCase.setCaseTime(caseTime);
                        floodCase.setCaseLocation(caseLocation);
                        floodCase.setCaseDescription(caseDescription);
                        
                        // 将未匹配的数据转为JSON存储（保留所有Excel原始数据）
                        // 同时将已匹配但可能不完整的数据也存入caseData，确保数据完整性
                        if (!caseDataMap.isEmpty())
                        {
                            floodCase.setCaseData(JSON.toJSONString(caseDataMap));
                        }
                        else
                        {
                            // 即使没有未匹配的列，也创建一个空的JSON对象，方便后续扩展
                            floodCase.setCaseData("{}");
                        }
                        
                        floodCase.setStatus("0");
                        floodCase.setCreateBy(operName);
                        
                        // 检查是否已存在（根据案例类型和名称）
                        FloodCase queryCase = new FloodCase();
                        queryCase.setCaseType(caseType);
                        queryCase.setCaseName(caseName);
                        List<FloodCase> existList = floodCaseMapper.selectFloodCaseList(queryCase);
                        
                        if (existList != null && !existList.isEmpty() && isUpdateSupport)
                        {
                            // 更新
                            FloodCase existCase = existList.get(0);
                            floodCase.setCaseId(existCase.getCaseId());
                            floodCase.setUpdateBy(operName);
                            floodCaseMapper.updateFloodCase(floodCase);
                            successNum++;
                            successMsg.append("<br/>Sheet[" + caseType + "] 第" + (i + 1) + "行案例 " + caseName + " 更新成功");
                        }
                        else if (existList == null || existList.isEmpty())
                        {
                            // 新增
                            floodCaseMapper.insertFloodCase(floodCase);
                            successNum++;
                            successMsg.append("<br/>Sheet[" + caseType + "] 第" + (i + 1) + "行案例 " + caseName + " 导入成功");
                        }
                        else
                        {
                            failureNum++;
                            failureMsg.append("<br/>Sheet[" + caseType + "] 第" + (i + 1) + "行案例 " + caseName + " 已存在");
                        }
                    }
                    catch (Exception e)
                    {
                        failureNum++;
                        failureMsg.append("<br/>Sheet[" + caseType + "] 第" + (i + 1) + "行导入失败：" + e.getMessage());
                        log.error("导入洪水案例Sheet[" + caseType + "] 第" + (i + 1) + "行失败", e);
                    }
                }
            }
        }
        catch (Exception e)
        {
            log.error("导入洪水案例失败", e);
            throw new ServiceException("导入失败：" + e.getMessage());
        }
        
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 从文本中提取流量值
     *
     * @param text 文本内容
     * @return 流量值
     */
    private String extractFlowValue(String text)
    {
        if (StringUtils.isEmpty(text))
        {
            return "";
        }
        // 匹配洪峰流量模式，如：11700m3/s, 13100m³/s, 34000m3/s等
        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("(\\d+(?:\\.\\d+)?)\\s*m[³3]?/s", 
            java.util.regex.Pattern.CASE_INSENSITIVE);
        java.util.regex.Matcher matcher = pattern.matcher(text);
        if (matcher.find())
        {
            return matcher.group(1) + "m³/s";
        }
        // 如果没有找到标准格式，返回包含"流量"的部分
        if (text.contains("流量"))
        {
            int index = text.indexOf("流量");
            int start = Math.max(0, index - 20);
            int end = Math.min(text.length(), index + 30);
            String flowPart = text.substring(start, end);
            return flowPart.trim();
        }
        return "";
    }

    /**
     * 从文本中提取降雨量值
     *
     * @param text 文本内容
     * @return 降雨量值
     */
    private String extractRainValue(String text)
    {
        if (StringUtils.isEmpty(text))
        {
            return "";
        }
        // 匹配降雨量模式，如：280.9mm, 325.2mm等
        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("(\\d+(?:\\.\\d+)?)\\s*mm", 
            java.util.regex.Pattern.CASE_INSENSITIVE);
        java.util.regex.Matcher matcher = pattern.matcher(text);
        StringBuilder result = new StringBuilder();
        while (matcher.find())
        {
            if (result.length() > 0)
            {
                result.append("; ");
            }
            result.append(matcher.group(1)).append("mm");
        }
        return result.toString();
    }

    /**
     * 从损失文本中提取人员伤亡信息
     *
     * @param text 损失文本
     * @return 人员伤亡信息
     */
    private String extractCasualties(String text)
    {
        if (StringUtils.isEmpty(text))
        {
            return "";
        }
        // 提取包含伤亡、死亡、受伤等关键词的句子
        String[] sentences = text.split("[。，；]");
        StringBuilder casualties = new StringBuilder();
        for (String sentence : sentences)
        {
            if (sentence.contains("伤亡") || sentence.contains("死亡") || sentence.contains("受伤") || 
                sentence.contains("遇难") || sentence.contains("失踪"))
            {
                if (casualties.length() > 0)
                {
                    casualties.append("；");
                }
                casualties.append(sentence.trim());
            }
        }
        return casualties.toString();
    }

    /**
     * 获取单元格值
     *
     * @param row 行
     * @param columnIndex 列索引
     * @return 单元格值
     */
    private String getCellValue(Row row, int columnIndex)
    {
        if (row == null || row.getCell(columnIndex) == null)
        {
            return "";
        }
        try
        {
            Cell cell = row.getCell(columnIndex);
            switch (cell.getCellType())
            {
                case STRING:
                    return cell.getStringCellValue().trim();
                case NUMERIC:
                    // 判断是否为日期
                    if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell))
                    {
                        return new java.text.SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue());
                    }
                    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:
                    return cell.getCellFormula();
                default:
                    return "";
            }
        }
        catch (Exception e)
        {
            return "";
        }
    }

    /**
     * 统计案例库总数
     *
     * @return 案例库总数
     */
    @Override
    public int countFloodCase()
    {
        return floodCaseMapper.countFloodCase();
    }
}
