package com.testor.module.hazard.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.biz.sys.dict.data.dao.SysDictDataDao;
import com.testor.biz.sys.dict.data.service.SysDictDataService;
import com.testor.biz.sys.user.model.domain.SysUser;
import com.testor.common.core.utils.StringUtils;
import com.testor.module.hazard.dao.HazardWorkPlanStatisticsDao;
import com.testor.module.hazard.model.dto.HazardWorkPlanStatisticsDto;
import com.testor.module.hazard.model.dto.HazardWorkPlanStatisticsResult;
import com.testor.module.hazard.model.dto.THazardWorkPlanDetailStatistics;
import com.testor.module.hazard.model.dto.THazardWorkPlanStatistics;
import com.testor.module.hazard.model.template.HazardWorkPlanStatisticsTemplate;
import com.testor.module.hazard.model.vo.HazardWorkPlanStatisticsVO;
import com.testor.module.hazard.service.HazardWorkPlanStatisticsService;
import com.testor.module.iam.service.SysUserService;
import com.testor.module.sys.service.NewSysDictDataService;
import com.testor.module.sys.service.TSysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class HazardWorkPlanStatisticsServiceImpl implements HazardWorkPlanStatisticsService {
    @Autowired
    private HazardWorkPlanStatisticsDao hazardWorkPlanStatisticsDao;

    @Autowired
    private NewSysDictDataService dictDataService;

    @Autowired
    private SysUserService userService;

    /**
     * 危险作业分布统计，根据单位
     *
     * @param param
     * @return
     */
    @Override
    public List<HazardWorkPlanStatisticsVO> statWorkPlanNumByOrg(HazardWorkPlanStatisticsDto param) {
        return hazardWorkPlanStatisticsDao.statWorkPlanNumByOrg(param);
    }

    /**
     * 危险作业数量统计，根据时间
     *
     * @param param
     * @return
     */
    @Override
    public List<HazardWorkPlanStatisticsVO> statWorkPlanNumByTime(HazardWorkPlanStatisticsDto param) {
        return hazardWorkPlanStatisticsDao.statWorkPlanNumByTime(param);
    }

    /**
     * 相关方作业统计
     *
     * @param param
     * @return
     */
    @Override
    public List<HazardWorkPlanStatisticsVO> statStakeholderWorkNum(HazardWorkPlanStatisticsDto param) {
        return hazardWorkPlanStatisticsDao.statStakeholderWorkNum(param);
    }

    /**
     * 租赁库占比统计
     *
     * @param param
     * @return
     */
    @Override
    public List<HazardWorkPlanStatisticsVO> statIsRentNum(HazardWorkPlanStatisticsDto param) {
        return hazardWorkPlanStatisticsDao.statIsRentNum(param);
    }

    /**
     * 危险作业人员统计
     *
     * @param param
     * @return
     */
    @Override
    public List<HazardWorkPlanStatisticsVO> statOperatorNum(HazardWorkPlanStatisticsDto param) {
        return hazardWorkPlanStatisticsDao.statOperatorNum(param);
    }

    @Override
    public List<THazardWorkPlanStatistics> selectHazardWorkPlanStatistics(HazardWorkPlanStatisticsDto hazardWorkPlanStatisticsDto) {
        return hazardWorkPlanStatisticsDao.selectHazardWorkPlanStatistics(hazardWorkPlanStatisticsDto);
    }

    @Override
    public Page<HazardWorkPlanStatisticsResult> selectWorkStatusDetailStatistics(HazardWorkPlanStatisticsDto query) {

        // 0. 获取所有字典值
        Map<String, List<String>> allDictValues = getAllDictValues();

        // 1. 执行四个独立的查询
        List<THazardWorkPlanDetailStatistics> workBasicDetailStatistics = hazardWorkPlanStatisticsDao.workBasicDetailStatistics(query);
        List<THazardWorkPlanDetailStatistics> workTypeDetailStatistics = hazardWorkPlanStatisticsDao.workTypeDetailStatistics(query);
        List<THazardWorkPlanDetailStatistics> workLevelDetailStatistics = hazardWorkPlanStatisticsDao.workLevelDetailStatistics(query);
        List<THazardWorkPlanDetailStatistics> workStatusDetailStatistics = hazardWorkPlanStatisticsDao.workStatusDetailStatistics(query);

        // 2. 创建结果列表
        List<HazardWorkPlanStatisticsResult> resultList = new ArrayList<>();

        // 3. 构建企业键值映射
        Map<String, HazardWorkPlanStatisticsResult> resultMap = new HashMap<>();

        // 3.1 处理基础数量统计
        for (THazardWorkPlanDetailStatistics basicStat : workBasicDetailStatistics) {
            String key = getOrgKey(basicStat.getRegionName(), basicStat.getBusinessDeptName(), basicStat.getCurrentOrgName());

            HazardWorkPlanStatisticsResult result = new HazardWorkPlanStatisticsResult();
            result.setRegionName(basicStat.getRegionName());
            result.setBusinessDeptName(basicStat.getBusinessDeptName());
            result.setCurrentOrgName(basicStat.getCurrentOrgName());
            result.setWorkCount(basicStat.getWorkCount());
            result.setOwnCount(basicStat.getOwnCount());
            result.setStakeholderCount(basicStat.getStakeholderCount());

            // 预初始化所有字典值为0
            result.setWorkTypeStats(initializeDictStats(allDictValues.get("workType")));
            result.setWorkLevelStats(initializeDictStats(allDictValues.get("workLevel")));
            result.setWorkStatusStats(initializeDictStats(allDictValues.get("workStatus")));

            resultMap.put(key, result);
        }

        // 3.2 处理作业类别统计
        for (THazardWorkPlanDetailStatistics typeStat : workTypeDetailStatistics) {
            String key = getOrgKey(typeStat.getRegionName(), typeStat.getBusinessDeptName(), typeStat.getCurrentOrgName());
            HazardWorkPlanStatisticsResult result = resultMap.get(key);

            if (result != null) {
                String workType = typeStat.getWorkType() != null ? typeStat.getWorkType() : "未知类别";
                Integer count = typeStat.getWorkTypeCount() != null ? typeStat.getWorkTypeCount() : 0;

                // 如果字典值不在预定义列表中，添加到字典值列表
                if (!result.getWorkTypeStats().containsKey(workType)) {
                    result.getWorkTypeStats().put(workType, 0);
                }
                result.getWorkTypeStats().put(workType, count);
            }
        }

        // 3.3 处理作业级别统计
        for (THazardWorkPlanDetailStatistics levelStat : workLevelDetailStatistics) {
            String key = getOrgKey(levelStat.getRegionName(), levelStat.getBusinessDeptName(), levelStat.getCurrentOrgName());
            HazardWorkPlanStatisticsResult result = resultMap.get(key);

            if (result != null) {
                String workLevel = levelStat.getWorkLevel() != null ? levelStat.getWorkLevel() : "未知级别";
                Integer count = levelStat.getWorkLevelCount() != null ? levelStat.getWorkLevelCount() : 0;

                // 如果字典值不在预定义列表中，添加到字典值列表
                if (!result.getWorkLevelStats().containsKey(workLevel)) {
                    result.getWorkLevelStats().put(workLevel, 0);
                }
                result.getWorkLevelStats().put(workLevel, count);
            }
        }

        // 3.4 处理作业状态统计
        for (THazardWorkPlanDetailStatistics statusStat : workStatusDetailStatistics) {
            String key = getOrgKey(statusStat.getRegionName(), statusStat.getBusinessDeptName(), statusStat.getCurrentOrgName());
            HazardWorkPlanStatisticsResult result = resultMap.get(key);

            if (result != null) {
                String workStatus = statusStat.getWorkStatus() != null ? statusStat.getWorkStatus() : "未知状态";
                Integer count = statusStat.getWorkStatusCount() != null ? statusStat.getWorkStatusCount() : 0;

                // 如果字典值不在预定义列表中，添加到字典值列表
                if (!result.getWorkStatusStats().containsKey(workStatus)) {
                    result.getWorkStatusStats().put(workStatus, 0);
                }
                result.getWorkStatusStats().put(workStatus, count);
            }
        }

        // 3.5 确保所有预定义字典值都存在（即使没有数据也显示为0）
        for (HazardWorkPlanStatisticsResult result : resultMap.values()) {
            ensureAllDictValuesPresent(result, allDictValues);
        }

        // 4. 将Map转换为List
        resultList.addAll(resultMap.values());

        // 5. 排序（按组织层级）
        resultList.sort((a, b) -> {
            int regionCompare = StringUtils.compare(a.getRegionName(), b.getRegionName());
            if (regionCompare != 0) return regionCompare;

            int deptCompare = StringUtils.compare(a.getBusinessDeptName(), b.getBusinessDeptName());
            if (deptCompare != 0) return deptCompare;

            return StringUtils.compare(a.getCurrentOrgName(), b.getCurrentOrgName());
        });

        // 6. 手动分页处理
        int total = resultList.size();
        int pageSize = query.getSize();
        int currentPage = query.getCurrent();

        // 计算分页起始和结束索引
        int startIndex = (currentPage - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, total);

        Page<HazardWorkPlanStatisticsResult> page = new Page<>(currentPage, pageSize);

        // 如果起始索引超出范围，返回空列表
        if (startIndex >= total) {
            page.setRecords(new ArrayList<>());
        } else {
            // 获取当前页的数据
            List<HazardWorkPlanStatisticsResult> pageRecords = resultList.subList(startIndex, endIndex);
            page.setRecords(pageRecords);
        }

        // 7. 设置分页信息
        page.setTotal(total);
        page.setPages((total + pageSize - 1) / pageSize); // 计算总页数

        return page;
    }

    /**
     * 初始化字典统计，所有值设为0
     */
    private Map<String, Integer> initializeDictStats(List<String> dictValues) {
        if (dictValues == null) {
            return new HashMap<>();
        }

        Map<String, Integer> stats = new LinkedHashMap<>();
        for (String dictValue : dictValues) {
            stats.put(dictValue, 0);
        }
        return stats;
    }

    /**
     * 确保所有预定义字典值都存在
     */
    private void ensureAllDictValuesPresent(HazardWorkPlanStatisticsResult result, Map<String, List<String>> allDictValues) {
        if (result == null || allDictValues == null) return;

        // 确保作业类别字典值完整
        if (allDictValues.containsKey("workType")) {
            for (String dictValue : allDictValues.get("workType")) {
                result.getWorkTypeStats().putIfAbsent(dictValue, 0);
            }
        }

        // 确保作业级别字典值完整
        if (allDictValues.containsKey("workLevel")) {
            for (String dictValue : allDictValues.get("workLevel")) {
                result.getWorkLevelStats().putIfAbsent(dictValue, 0);
            }
        }

        // 确保作业状态字典值完整
        if (allDictValues.containsKey("workStatus")) {
            for (String dictValue : allDictValues.get("workStatus")) {
                result.getWorkStatusStats().putIfAbsent(dictValue, 0);
            }
        }
    }

    private String getOrgKey(String regionName, String businessDeptName, String currentOrgName) {
        return (regionName != null ? regionName : "") + "|" +
                (businessDeptName != null ? businessDeptName : "") + "|" +
                (currentOrgName != null ? currentOrgName : "");
    }

    // 获取所有字典值的方法
    private Map<String, List<String>> getAllDictValues() {
        Map<String, List<String>> dictValues = new HashMap<>();

        // 获取作业类别字典值
        List<String> workTypeDicts = dictDataService.getDictValuesByDictId("42a87414a06a4f57b9d3ffb1907284b4");
        dictValues.put("workType", workTypeDicts != null ? workTypeDicts : new ArrayList<>());

        // 获取作业级别字典值
        List<String> workLevelDicts = dictDataService.getDictValuesByDictId("222842ea3bb4468bbbeaa3856a4f2731");
        dictValues.put("workLevel", workLevelDicts != null ? workLevelDicts : new ArrayList<>());

        // 获取作业状态字典值
        List<String> workStatusDicts = dictDataService.getDictValuesByDictId("60c11c98359b4cd09b7220202abf9e0b");
        dictValues.put("workStatus", workStatusDicts != null ? workStatusDicts : new ArrayList<>());

        return dictValues;
    }

        /**
         * 导出完整的危险作业统计数据（不分页，全部数据）
         * @param query 查询条件
         * @return 完整的导出数据列表
         */
        public List<HazardWorkPlanStatisticsTemplate> exportCompleteStatistics(HazardWorkPlanStatisticsDto query) {
            // 1. 设置不分页查询参数
            HazardWorkPlanStatisticsDto noPageQuery = new HazardWorkPlanStatisticsDto();
            // 复制查询条件
            BeanUtils.copyProperties(query, noPageQuery);
            // 设置不分页（获取所有数据）
            noPageQuery.setCurrent(1);
            noPageQuery.setSize(Integer.MAX_VALUE);

            // 2. 执行查询（获取完整数据，不分页）
            Page<HazardWorkPlanStatisticsResult> pageResult = selectWorkStatusDetailStatistics(noPageQuery);

            // 3. 获取所有记录（不分页）
            List<HazardWorkPlanStatisticsResult> allResults = pageResult.getRecords();

            // 4. 转换为导出模板
            return convertToExportTemplates(allResults);
        }

        /**
         * 将统计结果列表转换为导出模板列表
         */
        public List<HazardWorkPlanStatisticsTemplate> convertToExportTemplates(
                List<HazardWorkPlanStatisticsResult> statisticsResults) {

            List<HazardWorkPlanStatisticsTemplate> exportTemplates = new ArrayList<>();

            if (statisticsResults == null || statisticsResults.isEmpty()) {
                return exportTemplates;
            }

            // 设置序号
            int index = 1;
            for (HazardWorkPlanStatisticsResult result : statisticsResults) {
                HazardWorkPlanStatisticsTemplate template = convertSingleResult(result, index++);
                exportTemplates.add(template);
            }

            return exportTemplates;
        }

        /**
         * 转换单个统计结果为导出模板
         */
        private HazardWorkPlanStatisticsTemplate convertSingleResult(
                HazardWorkPlanStatisticsResult result, int index) {

            HazardWorkPlanStatisticsTemplate template = new HazardWorkPlanStatisticsTemplate();

            // 2. 设置组织信息
            template.setRegionName(result.getRegionName());
            template.setBusinessDeptName(result.getBusinessDeptName());
            template.setCurrentOrgName(result.getCurrentOrgName());

            // 3. 设置基础数量统计
            template.setWorkCount(result.getWorkCount() != null ? result.getWorkCount() : 0);
            template.setOwnCount(result.getOwnCount() != null ? result.getOwnCount() : 0);
            template.setStakeholderCount(result.getStakeholderCount() != null ? result.getStakeholderCount() : 0);

            // 4. 设置作业类别统计
            Map<String, Integer> workTypeStats = result.getWorkTypeStats();
            if (workTypeStats != null) {
                template.setWorkTypeIn(getValueOrZero(workTypeStats, "进仓作业"));
                template.setWorkTypeOut(getValueOrZero(workTypeStats, "出仓作业"));
                template.setWorkTypeFire(getValueOrZero(workTypeStats, "动火作业"));
                template.setWorkTypeLimitedSpace(getValueOrZero(workTypeStats, "有限空间作业"));
                template.setWorkTypeHoisting(getValueOrZero(workTypeStats, "吊装作业"));
                template.setWorkTypeHigh(getValueOrZero(workTypeStats, "高处作业"));
                template.setWorkTypeTempElectricity(getValueOrZero(workTypeStats, "临时用电作业"));
                template.setWorkTypeExcavation(getValueOrZero(workTypeStats, "动土作业"));
                template.setWorkTypeRoadClosure(getValueOrZero(workTypeStats, "断路作业"));
                template.setWorkTypeCirculationFumigation(getValueOrZero(workTypeStats, "环流熏蒸作业"));
                template.setWorkTypeFumigation(getValueOrZero(workTypeStats, "熏蒸作业"));
                template.setWorkTypeClosing(getValueOrZero(workTypeStats, "平仓作业"));
                template.setWorkTypeSiloCleaning(getValueOrZero(workTypeStats, "筒仓清仓作业"));
                template.setWorkTypeLiquidAmmonia(getValueOrZero(workTypeStats, "液氨接卸作业"));
                template.setWorkTypeUnknown(getValueOrZero(workTypeStats, "未知类别"));
            } else {
                // 如果为空，初始化所有值为0
                initializeWorkTypeStats(template);
            }

            // 5. 设置作业级别统计
            Map<String, Integer> workLevelStats = result.getWorkLevelStats();
            if (workLevelStats != null) {
                template.setWorkLevelHigh(getValueOrZero(workLevelStats, "高度危险"));
                template.setWorkLevelMedium(getValueOrZero(workLevelStats, "较大危险"));
                template.setWorkLevelLow(getValueOrZero(workLevelStats, "一般危险"));
                template.setWorkLevelUnknown(getValueOrZero(workLevelStats, "未知级别"));
            } else {
                initializeWorkLevelStats(template);
            }

            // 6. 设置作业状态统计
            Map<String, Integer> workStatusStats = result.getWorkStatusStats();
            if (workStatusStats != null) {
                template.setWorkStatusTechBriefing(getValueOrZero(workStatusStats, "技术交底"));
                template.setWorkStatusDraft(getValueOrZero(workStatusStats, "草稿"));
                template.setWorkStatusClosed(getValueOrZero(workStatusStats, "已关闭"));
                template.setWorkStatusPreCondition(getValueOrZero(workStatusStats, "作业前（条件确认）"));
                template.setWorkStatusPreRiskAnalysis(getValueOrZero(workStatusStats, "作业前（风险分析）"));
                template.setWorkStatusTimeoutCancel(getValueOrZero(workStatusStats, "已超时自动取消"));
                template.setWorkStatusCancelled(getValueOrZero(workStatusStats, "已取消"));
                template.setWorkStatusPreLicense(getValueOrZero(workStatusStats, "作业前（许可证）"));
                template.setWorkStatusUnknown(getValueOrZero(workStatusStats, "未知状态"));
            } else {
                initializeWorkStatusStats(template);
            }

            return template;
        }

        /**
         * 初始化作业类别统计为0
         */
        private void initializeWorkTypeStats(HazardWorkPlanStatisticsTemplate template) {
            template.setWorkTypeIn(0);
            template.setWorkTypeOut(0);
            template.setWorkTypeFire(0);
            template.setWorkTypeLimitedSpace(0);
            template.setWorkTypeHoisting(0);
            template.setWorkTypeHigh(0);
            template.setWorkTypeTempElectricity(0);
            template.setWorkTypeExcavation(0);
            template.setWorkTypeRoadClosure(0);
            template.setWorkTypeCirculationFumigation(0);
            template.setWorkTypeFumigation(0);
            template.setWorkTypeClosing(0);
            template.setWorkTypeSiloCleaning(0);
            template.setWorkTypeLiquidAmmonia(0);
            template.setWorkTypeUnknown(0);
        }

        /**
         * 初始化作业级别统计为0
         */
        private void initializeWorkLevelStats(HazardWorkPlanStatisticsTemplate template) {
            template.setWorkLevelHigh(0);
            template.setWorkLevelMedium(0);
            template.setWorkLevelLow(0);
            template.setWorkLevelUnknown(0);
        }

        /**
         * 初始化作业状态统计为0
         */
        private void initializeWorkStatusStats(HazardWorkPlanStatisticsTemplate template) {
            template.setWorkStatusTechBriefing(0);
            template.setWorkStatusDraft(0);
            template.setWorkStatusClosed(0);
            template.setWorkStatusPreCondition(0);
            template.setWorkStatusPreRiskAnalysis(0);
            template.setWorkStatusTimeoutCancel(0);
            template.setWorkStatusCancelled(0);
            template.setWorkStatusPreLicense(0);
            template.setWorkStatusUnknown(0);
        }

        /**
         * 从Map中获取值，如果没有则返回0
         */
        private Integer getValueOrZero(Map<String, Integer> map, String key) {
            if (map == null || key == null) {
                return 0;
            }
            Integer value = map.get(key);
            return value != null ? value : 0;
        }

}
