package com.zcloud.fire.check.command.query;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.cola.dto.PageResponse;
import com.zcloud.fire.check.command.convertor.*;
import com.zcloud.fire.check.domain.enums.CommonFlagEnum;
import com.zcloud.fire.check.domain.enums.CorpTypeEnum;
import com.zcloud.fire.check.domain.enums.HiddenCheckTypeEnum;
import com.zcloud.fire.check.domain.enums.UserTypeEnum;
import com.zcloud.fire.check.dto.CorpStatisticsPageQry;
import com.zcloud.fire.check.dto.FireBackCheckRecordPageQry;
import com.zcloud.fire.check.dto.FireCheckRecordPagePointQry;
import com.zcloud.fire.check.dto.FireCheckRecordPageQry;
import com.zcloud.fire.check.dto.clientobject.*;
import com.zcloud.fire.check.persistence.dataobject.*;
import com.zcloud.fire.check.persistence.repository.*;
import com.zcloud.gbscommon.utils.PageQueryHelper;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * web-app
 *
 * @Author zhaokai
 * @Date 2025-12-12 11:10:59
 */
@Component
@AllArgsConstructor
public class FireCheckRecordQueryExe {
    private final FireCheckRecordRepository fireCheckRecordRepository;
    private final FireCheckRecordCoConvertor fireCheckRecordCoConvertor;
    private final FireCheckRecordUserRepository fireCheckRecordUserRepository;
    private final FireCheckRecordHiddenRepository fireCheckRecordHiddenRepository;
    private final FireCheckRecordUserCoConvertor fireCheckRecordUserCoConvertor;
    private final FireCheckRecordHiddenCoConvertor fireCheckRecordHiddenCoConvertor;
    private final FireCheckRecordDeviceRepository fireCheckRecordDeviceRepository;
    private final FireCheckRecordDeviceCoConvertor fireCheckRecordDeviceCoConvertor;
    private final CorpInfoRepository corpInfoRepository;
    private final CorpInfoCoConvertor corpInfoCoConvertor;
    private final FireCheckListUserRepository fireCheckListUserRepository;
    private final FireCheckRecordPointRepository fireCheckRecordPointRepository;

    /**
     * 分页
     *
     * @param fireCheckRecordPageQry
     * @return
     */
    public PageResponse<FireCheckRecordCO> execute(FireCheckRecordPageQry fireCheckRecordPageQry) {
        Map<String, Object> params = PageQueryHelper.toHashMap(fireCheckRecordPageQry);
        PageResponse<FireCheckRecordDO> pageResponse = fireCheckRecordRepository.getCheckRecordList(params);
        List<FireCheckRecordCO> examCenterCOS = fireCheckRecordCoConvertor.converDOsToCOs(pageResponse.getData());
        return PageResponse.of(examCenterCOS, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
    }

    public PageResponse<FireBackCheckRecordCO> getCheckRecordList(FireBackCheckRecordPageQry qry) {
        Map<String, Object> params = PageQueryHelper.toHashMap(qry);

        PageResponse<FireCheckRecordDO> pageResponse = fireCheckRecordRepository.getCheckRecordList(params);
        List<FireBackCheckRecordCO> fireBackCheckRecordCOList = fireCheckRecordCoConvertor.converDOsToBackRecordCOs(pageResponse.getData());
        if(CollUtil.isEmpty(fireBackCheckRecordCOList)){
            return PageResponse.of(fireBackCheckRecordCOList, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
        }
        //涉及点位数和负责人补全
        List<String> fireCheckIdList =fireBackCheckRecordCOList.stream().map(FireBackCheckRecordCO::getFireCheckId).collect(Collectors.toList());
        //补充完整的用户负责人
        List<FireCheckListUserDO> fireCheckListStatisticDOList = fireCheckListUserRepository.getListUserByFireCheckIdList(fireCheckIdList);
        //fireCheckListUserDOList转换为key value username
        Map<String, String> fireCheckListUserDOMap = fireCheckListStatisticDOList.stream()
                .collect(Collectors.toMap(FireCheckListUserDO::getFireCheckId, FireCheckListUserDO::getUserName));

        //获取清单的检查数量
        //补充检查数和完整检查人
        fireBackCheckRecordCOList.forEach(fireBackCheckListCO -> {
            //补充检查数量
            if (CollUtil.isNotEmpty(fireCheckListUserDOMap) && fireCheckListUserDOMap.get(fireBackCheckListCO.getFireCheckId()) != null) {
                fireBackCheckListCO.setUserName(fireCheckListUserDOMap.get(fireBackCheckListCO.getFireCheckId()));
            }
        });



        return PageResponse.of(fireBackCheckRecordCOList, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
    }


    public FireCheckRecordInfoCO getChecKRecordInfo(String fireRecordId) {
        FireCheckRecordDO fireCheckRecordDO = fireCheckRecordRepository.getCheckRecordInfo(fireRecordId);

        if(fireCheckRecordDO == null){
            return null;
        }
        FireCheckRecordInfoCO fireCheckRecordCO = new FireCheckRecordInfoCO();
        BeanUtils.copyProperties(fireCheckRecordDO, fireCheckRecordCO);
        //补充负责人用户信息

        List<FireCheckListUserDO> listUserByFireCheckIdList = fireCheckListUserRepository.getListUserByFireCheckIdList(Arrays.asList(fireCheckRecordDO.getFireCheckId()));
        if(CollUtil.isNotEmpty(listUserByFireCheckIdList)){
            fireCheckRecordCO.setResponsibleUserNameList(listUserByFireCheckIdList.stream().map(FireCheckListUserDO::getUserName).collect(Collectors.joining(",")));
            fireCheckRecordCO.setResponsiblePostNameList(listUserByFireCheckIdList.stream().map(FireCheckListUserDO::getPostName).collect(Collectors.joining(",")));
        }

        //补充其他隐患信息
        List< FireCheckRecordHiddenDO> fireCheckRecordHiddenDOList = fireCheckRecordHiddenRepository.getChecKRecordHiddenList(fireRecordId, HiddenCheckTypeEnum.OTHER_HIDDEN.getCode());
        if(CollUtil.isNotEmpty(fireCheckRecordHiddenDOList)){
            fireCheckRecordCO.setFireCheckRecordHiddenList(fireCheckRecordHiddenCoConvertor.converDOsToCOs(fireCheckRecordHiddenDOList));
        }
        //添加检查内容
        List<FireCheckRecordDeviceDO> fireCheckRecordDeviceCOList = fireCheckRecordDeviceRepository.getCheckRecordDeviceList(fireCheckRecordDO.getFireRecordId());

        if(CollUtil.isNotEmpty(fireCheckRecordDeviceCOList)){
            List<FireCheckRecordDeviceCO> fireCheckRecordDeviceCOS = fireCheckRecordDeviceCoConvertor.converDOsToCOs(fireCheckRecordDeviceCOList);
            //补充隐患信息
            //fireCheckRecordDeviceCOS获取List id
            List<String> idList = fireCheckRecordDeviceCOS.stream().map(FireCheckRecordDeviceCO::getFireRecordDeviceId).collect(Collectors.toList());
            List<FireCheckRecordHiddenDO> checKRecordDeviceHiddenList = fireCheckRecordHiddenRepository.getChecKRecordDeviceList(idList);
            Map<String, FireCheckRecordHiddenDO> fireCheckRecordHiddenDOMap = checKRecordDeviceHiddenList.stream()
                    .collect(Collectors.toMap(FireCheckRecordHiddenDO::getFireRecordDeviceId, Function.identity()));

            //补充隐患信息
            fireCheckRecordDeviceCOS.forEach(info -> {
                FireCheckRecordHiddenDO fireCheckRecordHiddenDO = fireCheckRecordHiddenDOMap.get(info.getFireRecordDeviceId());
                if(fireCheckRecordHiddenDO != null){
                    info.setFireCheckRecordHiddenCO(fireCheckRecordHiddenCoConvertor.convertToCO(fireCheckRecordHiddenDO));
                }
            });
            fireCheckRecordCO.setFireCheckRecordDeviceList(fireCheckRecordDeviceCOS);
        }

        return fireCheckRecordCO;
    }

    public FireCheckRecordInfoCO getInfoById(Long id) {
        FireCheckRecordDO fireCheckRecordDO = fireCheckRecordRepository.getById( id);
        if(fireCheckRecordDO == null){
            return null;
        }
        FireCheckRecordInfoCO checKRecordInfo = getChecKRecordInfo(fireCheckRecordDO.getFireRecordId());


        return checKRecordInfo;
    }

    public PageResponse<CorpCheckStatisticsCO> corpCheckRecordList(CorpStatisticsPageQry qry) {
        Map<String, Object> params = PageQueryHelper.toHashMap(qry);
        //企业端
        params.put("inType", CorpTypeEnum.getCodesByEnterpriseType(UserTypeEnum.QY.getCode()));
        params.put("eqUseFlag", CommonFlagEnum.YES.getCode());

        PageResponse<CorpInfoDO> pageResponse = corpInfoRepository.listPage(params);
        if(CollUtil.isEmpty(pageResponse.getData())){
            return PageResponse.of(null, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
        }

        List<CorpCheckStatisticsCO> examCenterCOS = corpInfoCoConvertor.converCorpDOsToCorpCheckStatisticsCO(pageResponse.getData());
        //获取企业id
        List<Long> corpinfoIds = examCenterCOS.stream().map(CorpCheckStatisticsCO::getId).collect(Collectors.toList());
        //获取消防区域数量
        List<DataStatisticDO> fireRegionCountMap = fireCheckRecordRepository.DataStatisticDO(corpinfoIds);
        examCenterCOS.forEach(info -> {
            info.setCheckCount(fireRegionCountMap.stream()
                    .filter(item -> item.getCorpinfoId().equals(info.getId()))
                    .map(DataStatisticDO::getTotalCount)
                    .findFirst()
                    .orElse(0));
        });

        return PageResponse.of(examCenterCOS, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
    }

    public PageResponse<FireCheckRecordCO> getCheckRecordPageH5(FireCheckRecordPagePointQry qry) {
        Map<String, Object> params = PageQueryHelper.toHashMap(qry);
        PageResponse<FireCheckRecordDO> pageResponse = fireCheckRecordRepository.getCheckRecordPageH5(params);
        List<FireCheckRecordCO> examCenterCOS = fireCheckRecordCoConvertor.converDOsToCOs(pageResponse.getData());
        if(CollUtil.isEmpty(examCenterCOS)){
            return PageResponse.of(null, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
        }
        return PageResponse.of(examCenterCOS, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
    }

    public PageResponse<FireCheckRecordInfoCO> getCheckRecordPageH5New(FireCheckRecordPagePointQry qry) {
        Map<String, Object> params = PageQueryHelper.toHashMap(qry);
        PageResponse<FireCheckRecordDO> pageResponse = fireCheckRecordRepository.getCheckRecordPageH5New(params);

        List<FireCheckRecordInfoCO> resultCOList =  fireCheckRecordCoConvertor.converDOsToBackRecordInfoCOs(pageResponse.getData());
        if(CollUtil.isEmpty(resultCOList)){
            return PageResponse.of(null, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
        }
        // 提取所有记录ID用于批量查询
        List<String> fireRecordIdList = resultCOList.stream()
                .map(FireCheckRecordInfoCO::getFireRecordId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        // 批量查询其他隐患信息
        batchQueryAndSetOtherHiddenInfo(resultCOList, fireRecordIdList);

        // 批量查询设备检查信息及对应隐患
        batchQueryAndSetDeviceInfo(resultCOList, fireRecordIdList);

        return PageResponse.of(resultCOList, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
    }
    /**
     * 批量查询并设置其他隐患信息
     */
    private void batchQueryAndSetOtherHiddenInfo(List<FireCheckRecordInfoCO> resultCOList, List<String> fireRecordIdList) {
        if (CollUtil.isEmpty(fireRecordIdList)) {
            return;
        }
        List<FireCheckRecordHiddenDO> otherHiddenList = fireCheckRecordHiddenRepository
                .getChecKRecordHiddenListByRecordIdList(fireRecordIdList, HiddenCheckTypeEnum.OTHER_HIDDEN.getCode());

        if (CollUtil.isEmpty(otherHiddenList)) {
            return;
        }
        // 按记录ID分组其他隐患信息
        Map<String, List<FireCheckRecordHiddenDO>> otherHiddenGroupMap = otherHiddenList.stream()
                .collect(Collectors.groupingBy(FireCheckRecordHiddenDO::getFireRecordId));
        // 设置每个记录的其他隐患信息
        resultCOList.forEach(recordCO -> {
            List<FireCheckRecordHiddenDO> hiddenList = otherHiddenGroupMap.get(recordCO.getFireRecordId());
            if (CollUtil.isNotEmpty(hiddenList)) {
                recordCO.setFireCheckRecordHiddenList(fireCheckRecordHiddenCoConvertor.converDOsToCOs(hiddenList));
            }
        });
    }

    /**
     * 批量查询并设置设备检查信息及对应隐患
     */
    private void batchQueryAndSetDeviceInfo(List<FireCheckRecordInfoCO> resultCOList, List<String> fireRecordIdList) {
        if (CollUtil.isEmpty(fireRecordIdList)) {
            return;
        }
        // 批量查询所有设备检查记录
        List<FireCheckRecordDeviceDO> deviceRecordList = fireCheckRecordDeviceRepository
                .getCheckRecordDeviceListByRecordIdList(fireRecordIdList);

        if (CollUtil.isEmpty(deviceRecordList)) {
            return;
        }

        // 按记录ID分组设备检查信息
        Map<String, List<FireCheckRecordDeviceDO>> deviceGroupMap = deviceRecordList.stream()
                .collect(Collectors.groupingBy(FireCheckRecordDeviceDO::getFireRecordId));

        // 提取所有设备记录ID用于查询设备隐患
        List<String> deviceIdList = deviceRecordList.stream()
                .map(FireCheckRecordDeviceDO::getFireRecordDeviceId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        // 查询设备相关的隐患信息
        List<FireCheckRecordHiddenDO> deviceHiddenList = CollUtil.isNotEmpty(deviceIdList) ?
                fireCheckRecordHiddenRepository.getChecKRecordDeviceList(deviceIdList) : Collections.emptyList();

        // 按设备ID分组隐患信息
        Map<String, FireCheckRecordHiddenDO> deviceHiddenMap = deviceHiddenList.stream()
                .collect(Collectors.toMap(
                        FireCheckRecordHiddenDO::getFireRecordDeviceId,
                        Function.identity(),
                        (existing, replacement) -> existing // 处理重复key的情况
                ));

        // 为每个记录设置设备检查信息和对应隐患
        resultCOList.forEach(recordCO -> {
            List<FireCheckRecordDeviceDO> deviceDOList = deviceGroupMap.get(recordCO.getFireRecordId());
            if (CollUtil.isNotEmpty(deviceDOList)) {
                List<FireCheckRecordDeviceCO> deviceCOList = fireCheckRecordDeviceCoConvertor.converDOsToCOs(deviceDOList);

                // 为每个设备设置对应的隐患信息
                deviceCOList.forEach(deviceCO -> {
                    FireCheckRecordHiddenDO hiddenDO = deviceHiddenMap.get(deviceCO.getFireRecordDeviceId());
                    if (hiddenDO != null) {
                        deviceCO.setFireCheckRecordHiddenCO(fireCheckRecordHiddenCoConvertor.convertToCO(hiddenDO));
                    }
                });

                recordCO.setFireCheckRecordDeviceList(deviceCOList);
            }
        });
    }
}

