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

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.biz.sys.dict.data.model.domain.SysDictData;
import com.testor.biz.sys.dict.data.service.SysDictDataService;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.org.service.SysOrgService;
import com.testor.biz.sys.user.model.domain.SysUser;
import com.testor.module.emergency.model.vo.TContingencyPlanVO;
import com.testor.module.hazard.dao.THazardWorkPlanCheckDao;
import com.testor.module.hazard.model.domain.THazardWorkPlan;
import com.testor.module.hazard.model.domain.THazardWorkPlanCheck;
import com.testor.module.hazard.model.dto.HazardWorkPlanCheckEnterpriseComplianceDto;
import com.testor.module.hazard.model.dto.HazardWorkPlanCheckStatsDTO;
import com.testor.module.hazard.model.dto.THazardWorkPlanCheckParam;
import com.testor.module.hazard.model.vo.HazardWorkPlanCheckComplianceStatisticsVO;
import com.testor.module.hazard.model.vo.HazardWorkPlanCheckProblemCountStatisticsVO;
import com.testor.module.hazard.model.vo.HazardWorkPlanCheckProblemTypeStatisticsVO;
import com.testor.module.hazard.model.vo.HazardWorkPlanCheckVO;
import com.testor.module.hazard.service.THazardWorkPlanCheckService;
import com.testor.module.iam.service.SysUserService;
import com.testor.module.notice.dao.TSysOrgDao;
import com.testor.module.notice.model.domain.TSysOrg;
import com.testor.module.safe.model.domain.TSafeHazardOrg;
import com.testor.module.safe.model.vo.TSafeHazardExportVO;
import com.testor.module.safe.model.vo.TSafeHazardOrgStatisticsVO;
import com.testor.module.safe.service.impl.TSafeHazardOrgServiceImpl;
import com.testor.module.sys.dao.NewSysOrgDao;
import com.testor.module.sys.model.domian.NewSysOrg;
import com.testor.module.sys.service.NewSysDictDataService;
import com.testor.module.sys.service.NewSysOrgService;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.core.helper.IdHelper;
import com.tongtech.tfw.backend.core.helper.ObjectHelper;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.bean.BeanHelper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.tongtech.tfw.backend.common.models.supers.SuperServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * 危险作业计划监督检查Service业务层处理
 * 
 * @author testor-framework
 * @date 2025-04-16 10:09:22
 */
@Service
public class THazardWorkPlanCheckServiceImpl extends SuperServiceImpl<THazardWorkPlanCheckDao, THazardWorkPlanCheck> implements THazardWorkPlanCheckService
{

    private static final Logger logger = LoggerFactory.getLogger(TSafeHazardOrgServiceImpl.class);

    @Autowired(required = false)
    private THazardWorkPlanCheckDao tHazardWorkPlanCheckDao;

    @Autowired
    private TSysOrgDao orgDao;

    @Autowired
    private SysOrgService sysOrgService;

    @Autowired
    private SysUserService userService;

    @Autowired
    private NewSysDictDataService dictDataService;

    @Autowired
    private NewSysOrgDao newSysOrgDao;


    @Override
    public Page<THazardWorkPlanCheck> selectTHazardWorkPlanCheckList(THazardWorkPlanCheckParam tHazardWorkPlanCheckParam) {
        IPage<THazardWorkPlanCheck> page = new Page<>(Long.valueOf(tHazardWorkPlanCheckParam.getPage()), Long.valueOf(tHazardWorkPlanCheckParam.getLimit()));
        return this.baseMapper.selectTHazardWorkPlanCheckList(page,tHazardWorkPlanCheckParam);
    }

    @Override
    public Page<THazardWorkPlanCheck> selectAppTHazardWorkPlanCheckList(THazardWorkPlanCheckParam tHazardWorkPlanCheckParam) {
        IPage<THazardWorkPlanCheck> page = new Page<>(Long.valueOf(tHazardWorkPlanCheckParam.getPage()), Long.valueOf(tHazardWorkPlanCheckParam.getLimit()));
        return this.baseMapper.selectAppTHazardWorkPlanCheckList(page,tHazardWorkPlanCheckParam);
    }

    @Override
    public Page<THazardWorkPlanCheck> selectTHazardWorkPlanCheckManageList(THazardWorkPlanCheckParam tHazardWorkPlanCheckParam) {
        /*tHazardWorkPlanCheckParam.setStartTime(montageStartTime(tHazardWorkPlanCheckParam.getStartTime()));
        tHazardWorkPlanCheckParam.setEndTime(montageEndTime(tHazardWorkPlanCheckParam.getEndTime()));*/
        IPage<THazardWorkPlanCheck> page = new Page<>(Long.valueOf(tHazardWorkPlanCheckParam.getPage()), Long.valueOf(tHazardWorkPlanCheckParam.getLimit()));
        List<String> orgIdList = new ArrayList<>();
        if(null != tHazardWorkPlanCheckParam.getOrgIdList() && tHazardWorkPlanCheckParam.getOrgIdList().size()>0){
            tHazardWorkPlanCheckParam.setOrgIdList(orgDao.selectAllSubId(tHazardWorkPlanCheckParam.getOrgIdList()));
            orgIdList.addAll(tHazardWorkPlanCheckParam.getOrgIdList());
        }else{
            orgIdList.addAll(orgDao.selectOrgIdAllSubId(ContextUtils.getLoginUser().getOrgId()));
        }
        tHazardWorkPlanCheckParam.setOrgIdList(orgIdList);
        return this.baseMapper.selectTHazardWorkPlanCheckManageList(page,tHazardWorkPlanCheckParam);
    }

    @Override
    public THazardWorkPlanCheck addEntity(THazardWorkPlanCheck addRequest) {
        if(ObjectHelper.isNotEmpty(addRequest)){
            // TODO 按需求添加数据去重，特殊值设定，业务异常
            String id = IdHelper.getId32bit();
            THazardWorkPlanCheck data= BeanHelper.beanToBean(addRequest,  THazardWorkPlanCheck.class);
            data.setId(id);
            boolean result= this.save(data);
            if(result){
                THazardWorkPlanCheck newEntity = new THazardWorkPlanCheck();
                newEntity.setId(id);
                return newEntity;
            }
		}
        return null;
    }

    @Override
    public THazardWorkPlanCheck detail(String id) {
        return this.baseMapper.detail(id);
    }

    @Override
    public void exportEntity(THazardWorkPlanCheckParam param, HttpServletResponse response) {
        try{
            List<HazardWorkPlanCheckVO> hazardWorkPlanCheckVOList = new ArrayList<>();

            param.setStartTime(montageStartTime(param.getStartTime()));
            param.setEndTime(montageEndTime(param.getEndTime()));
            List<THazardWorkPlanCheck> tHazardWorkPlanCheckPage = this.baseMapper.selectTHazardWorkPlanCheckManageExportList(param);

            int i = 1;
            for (THazardWorkPlanCheck entity : tHazardWorkPlanCheckPage) {
                HazardWorkPlanCheckVO vo = new HazardWorkPlanCheckVO();
                BeanUtils.copyProperties(entity, vo);  // 复制属性
                vo.setNumber(i);
                vo.setIsCompliant(vo.getIsCompliant().equals("1")?"是":"否");
                i =i+1;
                hazardWorkPlanCheckVOList.add(vo);
            }

            logger.info("**************************************写入模板*****************************");

            String fileName = "监督检查导出明细";
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");


            WriteSheet dealerSheet = EasyExcel.writerSheet(0, "监督检查导出明细")
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).head(HazardWorkPlanCheckVO.class).build();
            ExcelWriter build = EasyExcelFactory.write(response.getOutputStream()).build();
            build.write(hazardWorkPlanCheckVOList,dealerSheet);
            build.finish();
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }


    @Override
    public List<HazardWorkPlanCheckComplianceStatisticsVO> selectCheckComplianceStatistics(THazardWorkPlanCheckParam tHazardWorkPlanCheckParam) {

        tHazardWorkPlanCheckParam.setStartTime(montageStartTime(tHazardWorkPlanCheckParam.getStartTime()));
        tHazardWorkPlanCheckParam.setEndTime(montageEndTime(tHazardWorkPlanCheckParam.getEndTime()));

        String orgId = tHazardWorkPlanCheckParam.getOrgId();
        if (StringHelper.isEmpty(orgId)) {
            // 获取登录企业
            orgId = ContextUtils.getLoginUser().getOrgId();
        }
        String finalOrgId = orgId;
        List<String> orgIds = new ArrayList<>();
        if (tHazardWorkPlanCheckParam.getOrgIdList() != null && tHazardWorkPlanCheckParam.getOrgIdList().size() > 0) {
            //orgIds = tHazardWorkPlanCheckParam.getOrgIdList();
            //如果只查当前机构数据
            if (tHazardWorkPlanCheckParam.isThisOrg()) {
                orgIds = tHazardWorkPlanCheckParam.getOrgIdList();
            } else {
                List<String> orgIdList = tHazardWorkPlanCheckParam.getOrgIdList();
                for(String id : orgIdList){
                    List<String> ids = sysOrgService.list(new QueryWrapper<SysOrg>().eq(SysOrg.PARENT_ID, id).ne(SysOrg.STATUS, BizConstants.STATUS_DELETE).eq(SysOrg.IS_DEPT, 0).orderByAsc("tree_sort")).stream().map(SysOrg::getOrgId).collect(Collectors.toList());
                    //如果下级机构为空
                    if (ids == null || ids.size() == 0) {
                        //存入当前机构
                        ids.add(finalOrgId);
                    }
                    orgIds.addAll(ids);
                }
            }
        }else {
            //如果只查当前机构数据
            if (tHazardWorkPlanCheckParam.isThisOrg()) {
                orgIds.add(orgId);
            } else {
                List<String> ids = sysOrgService.list(new QueryWrapper<SysOrg>().eq(SysOrg.PARENT_ID, finalOrgId).ne(SysOrg.STATUS, BizConstants.STATUS_DELETE).eq(SysOrg.IS_DEPT, 0).orderByAsc("tree_sort")).stream().map(SysOrg::getOrgId).collect(Collectors.toList());
                //如果下级机构为空
                if (ids == null || ids.size() == 0) {
                    //存入当前机构
                    ids.add(finalOrgId);
                }
                orgIds.addAll(ids);
            }
        }

        List<HazardWorkPlanCheckComplianceStatisticsVO> hazardWorkPlanCheckComplianceStatisticsVOS = new ArrayList<>();
        orgIds.stream().forEach(item -> {
            HazardWorkPlanCheckComplianceStatisticsVO hazardWorkPlanCheckComplianceStatisticsVO = new HazardWorkPlanCheckComplianceStatisticsVO();
            List<String> ids = new ArrayList<>();
            if (tHazardWorkPlanCheckParam.isThisOrg()){
                ids.add(finalOrgId);
            }else {
                //如果下级机构为空
                ids = sysOrgService.list(new QueryWrapper<SysOrg>().and(sysOrgQueryWrapper -> sysOrgQueryWrapper.like(SysOrg.PARENT_IDS, item).or().eq(SysOrg.ORG_ID,item))
                        .ne(SysOrg.STATUS, BizConstants.STATUS_DELETE).eq(SysOrg.IS_DEPT, 0).orderByAsc("tree_sort")).stream().map(SysOrg::getOrgId).collect(Collectors.toList());
                if (ids == null || ids.size() == 0) {
                    //存入当前机构
                    ids.add(finalOrgId);

                }
            }
            //tHazardWorkPlanCheckParam.setOrgIdList(ids);
            tHazardWorkPlanCheckParam.setOrgIdList(ids);
            hazardWorkPlanCheckComplianceStatisticsVO = this.baseMapper.selectCheckComplianceStatistics(tHazardWorkPlanCheckParam).get(0);
            hazardWorkPlanCheckComplianceStatisticsVO.setOrgId(item);
            hazardWorkPlanCheckComplianceStatisticsVO.setOrgName(sysOrgService.getById(item).getOrgName());
            hazardWorkPlanCheckComplianceStatisticsVOS.add(hazardWorkPlanCheckComplianceStatisticsVO);
        });


        return hazardWorkPlanCheckComplianceStatisticsVOS;
    }

    @Override
    public List<HazardWorkPlanCheckProblemTypeStatisticsVO> selectCheckProblemTypeStatistics(THazardWorkPlanCheckParam tHazardWorkPlanCheckParam) {
        if (CollectionUtils.isEmpty(tHazardWorkPlanCheckParam.getOrgIdList())) {
            List<String> orgIdList = new ArrayList<>();
            String orgId = ContextUtils.getLoginUser().getOrgId();
            orgIdList.add(orgId);
            orgIdList.addAll(newSysOrgDao.childOrgIds(orgId));
            tHazardWorkPlanCheckParam.setOrgIdList(orgIdList);
        }

        tHazardWorkPlanCheckParam.setStartTime(montageStartTime(tHazardWorkPlanCheckParam.getStartTime()));
        tHazardWorkPlanCheckParam.setEndTime(montageEndTime(tHazardWorkPlanCheckParam.getEndTime()));
        return this.baseMapper.selectCheckProblemTypeStatistics(tHazardWorkPlanCheckParam);
    }

    @Override
    public List<HazardWorkPlanCheckProblemCountStatisticsVO> selectCheckProblemCountStatistics(THazardWorkPlanCheckParam tHazardWorkPlanCheckParam) {
        if (CollectionUtils.isEmpty(tHazardWorkPlanCheckParam.getOrgIdList())) {
            List<String> orgIdList = new ArrayList<>();
            String orgId = ContextUtils.getLoginUser().getOrgId();
            orgIdList.add(orgId);
            orgIdList.addAll(newSysOrgDao.childOrgIds(orgId));
            tHazardWorkPlanCheckParam.setOrgIdList(orgIdList);
        }
        tHazardWorkPlanCheckParam.setStartTime(montageStartTime(tHazardWorkPlanCheckParam.getStartTime()));
        tHazardWorkPlanCheckParam.setEndTime(montageEndTime(tHazardWorkPlanCheckParam.getEndTime()));
        return this.baseMapper.selectCheckProblemCountStatistics(tHazardWorkPlanCheckParam);
    }

    @Override
    public HazardWorkPlanCheckStatsDTO selectHazardWorkPlanCheckStats(THazardWorkPlanCheckParam tHazardWorkPlanCheckParam) {
        // 参数验证
        if (StringUtils.isBlank(tHazardWorkPlanCheckParam.getUserId())) {
            throw new IllegalArgumentException("用户ID不能为空");
        }

        SysUser user = userService.getById(tHazardWorkPlanCheckParam.getUserId());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        tHazardWorkPlanCheckParam.setOrgId(user.getOrgId());
        //tHazardWorkPlanCheckParam.setOrgId("69223d5d1fa84ff29a0c11863d1b00b7");
        HazardWorkPlanCheckStatsDTO hazardWorkPlanCheckStatsDTO = baseMapper.selectHazardWorkPlanCheckStats(tHazardWorkPlanCheckParam);

        // 计算合规比例（合规企业数/企业总数）
        if (hazardWorkPlanCheckStatsDTO.getComplianceBasicUnitCount() != null && hazardWorkPlanCheckStatsDTO.getComplianceBasicUnitCount() > 0
            && hazardWorkPlanCheckStatsDTO.getBasicUnitCount() != null && hazardWorkPlanCheckStatsDTO.getBasicUnitCount() > 0) {
            double ratio = (double) hazardWorkPlanCheckStatsDTO.getComplianceBasicUnitCount()
                    / hazardWorkPlanCheckStatsDTO.getBasicUnitCount();
            double truncatedRatio = truncateToTwoDecimals(ratio);
            hazardWorkPlanCheckStatsDTO.setComplianceRatio(truncatedRatio);
        } else {
            hazardWorkPlanCheckStatsDTO.setComplianceRatio(0.0);
        }

        return hazardWorkPlanCheckStatsDTO;
    }

    public static double truncateToTwoDecimals(double value) {
        return Math.floor(value * 100);
    }

    @Override
    public List<HazardWorkPlanCheckEnterpriseComplianceDto> enterpriseComplianceNumber(THazardWorkPlanCheckParam tHazardWorkPlanCheckParam) {
        if (StringUtils.isBlank(tHazardWorkPlanCheckParam.getUserId())) {
            throw new IllegalArgumentException("用户ID不能为空");
        }

        SysUser user = userService.getById(tHazardWorkPlanCheckParam.getUserId());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        tHazardWorkPlanCheckParam.setOrgId(user.getOrgId());
        List<HazardWorkPlanCheckEnterpriseComplianceDto> hazardWorkPlanCheckEnterpriseComplianceDtos = new ArrayList<>();
        List<TSysOrg> tSysOrgs = orgDao.selectOrgNameByParentId(user.getOrgId());

        // 先处理中粮贸易
        HazardWorkPlanCheckEnterpriseComplianceDto zhongliangTrade = null;
        for (TSysOrg sysOrg : tSysOrgs) {
            tHazardWorkPlanCheckParam.setOrgId(sysOrg.getOrgId());
            HazardWorkPlanCheckEnterpriseComplianceDto dto = new HazardWorkPlanCheckEnterpriseComplianceDto(
                    sysOrg.getOrgName(), baseMapper.selectComplianceCount(tHazardWorkPlanCheckParam));

            if (sysOrg.getOrgName().contains("中粮贸易")) {
                zhongliangTrade = dto; // 保存中粮贸易
            } else {
                hazardWorkPlanCheckEnterpriseComplianceDtos.add(dto);
            }
        }

        // 对其他企业按count倒序排序
        hazardWorkPlanCheckEnterpriseComplianceDtos.sort((o1, o2) -> {
            if (o1.getCount() == null && o2.getCount() == null) {
                return 0;
            }
            if (o1.getCount() == null) {
                return 1;
            }
            if (o2.getCount() == null) {
                return -1;
            }
            return o2.getCount().compareTo(o1.getCount());
        });

        // 将中粮贸易添加到列表的第一个位置
        if (zhongliangTrade != null) {
            hazardWorkPlanCheckEnterpriseComplianceDtos.add(0, zhongliangTrade);
        }

        return hazardWorkPlanCheckEnterpriseComplianceDtos;
    }

    @Override
    public List<HazardWorkPlanCheckProblemCountStatisticsVO> selectProblemCountStatistics(THazardWorkPlanCheckParam tHazardWorkPlanCheckParam) {
        if (StringUtils.isBlank(tHazardWorkPlanCheckParam.getUserId())) {
            throw new IllegalArgumentException("用户ID不能为空");
        }

        SysUser user = userService.getById(tHazardWorkPlanCheckParam.getUserId());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        tHazardWorkPlanCheckParam.setOrgId(user.getOrgId());
        List<HazardWorkPlanCheckProblemCountStatisticsVO> problemCountStatistics = new ArrayList<>();
        for (SysDictData sysDictData : dictDataService.getDictId("736049b40cb04b1fb5c2ef5385655ee3")) {
            problemCountStatistics.add(new HazardWorkPlanCheckProblemCountStatisticsVO(sysDictData.getDictValue(),baseMapper.selectNoComplianceCount(tHazardWorkPlanCheckParam,sysDictData.getDictDataId())));
        }

        return problemCountStatistics;
    }

    @Override
    public Page<HazardWorkPlanCheckProblemCountStatisticsVO> corporateComplianceRate(THazardWorkPlanCheckParam tHazardWorkPlanCheckParam) {
        if (StringUtils.isBlank(tHazardWorkPlanCheckParam.getUserId())) {
            throw new IllegalArgumentException("用户ID不能为空");
        }

        SysUser user = userService.getById(tHazardWorkPlanCheckParam.getUserId());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        Long page =
                StringHelper.isEmpty(tHazardWorkPlanCheckParam.getPage()) ? BizConstants.PAGE : Long.valueOf(tHazardWorkPlanCheckParam.getPage());
        Long limit =
                StringHelper.isEmpty(tHazardWorkPlanCheckParam.getLimit()) ? BizConstants.LIMIT : Long.valueOf(tHazardWorkPlanCheckParam.getLimit());
        Page<THazardWorkPlan> resultPage = new Page<>(page, limit);
        tHazardWorkPlanCheckParam.setOrgId(user.getOrgId());
        return baseMapper.corporateComplianceRate(resultPage,tHazardWorkPlanCheckParam);
    }

    public String montageStartTime(String startTime){
        if(startTime !=null && !"".equals(startTime) ){
            startTime = startTime+" 00:00:00";
        }
        return startTime;
    }

    public String montageEndTime(String endTime){
        if(endTime !=null && !"".equals(endTime) ){
            endTime = endTime+" 23:59:59";
        }
        return endTime;
    }

}
