package com.zcloud.fire.check.command;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.zcloud.fire.check.domain.enums.CheckFlagEnum;
import com.zcloud.fire.check.domain.enums.CheckRecordNormalFlagEnum;
import com.zcloud.fire.check.domain.gateway.FireCheckRecordDeviceGateway;
import com.zcloud.fire.check.domain.gateway.FireCheckRecordGateway;
import com.zcloud.fire.check.domain.gateway.FireCheckRecordHiddenGateway;
import com.zcloud.fire.check.domain.gateway.FireCheckRecordPointGateway;
import com.zcloud.fire.check.domain.model.*;
import com.zcloud.fire.check.dto.AppCheckRecordPointAddCmd;
import com.zcloud.fire.check.dto.FireCheckRecordDeviceAddCmd;
import com.zcloud.fire.check.dto.FireCheckRecordPointAddCmd;
import com.zcloud.fire.check.dto.clientobject.FireCheckRecordPointCO;
import com.zcloud.fire.check.persistence.dataobject.*;
import com.zcloud.fire.check.persistence.repository.*;
import com.zcloud.gbscommon.zcloudhidden.face.ZcloudHiddenFacade;
import com.zcloud.gbscommon.zcloudhidden.request.HiddenAddCmd;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.function.Function;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * web-app
 *
 * @Author zhaokai
 * @Date 2025-12-12 11:10:19
 */
@Component
@AllArgsConstructor
@Slf4j
public class FireCheckRecordPointAddExe {
    private final FireCheckRecordPointGateway fireCheckRecordPointGateway;
    private final FireCheckRecordGateway fireCheckRecordGateway;
    private final FirePointRepository firePointRepository;
    private final FireDeviceRepository fireDeviceRepository;
    private final FireCheckRecordDeviceGateway fireCheckRecordDeviceGateway;
    private final FireCheckRecordDeviceRepository fireCheckRecordDeviceRepository;
    private final FireCheckRecordHiddenGateway fireCheckRecordHiddenGateway;
    private final FireCheckRecordHiddenRepository fireCheckRecordHiddenRepository;
    private final FireCheckStandardRepository fireCheckStandardRepository;

    @DubboReference
    private ZcloudHiddenFacade zcloudHiddenFacade;

    @Transactional(rollbackFor = Exception.class)
    public boolean execute(FireCheckRecordPointAddCmd cmd) {
        FireCheckRecordPointE fireCheckRecordPointE = new FireCheckRecordPointE();
        BeanUtils.copyProperties(cmd, fireCheckRecordPointE);
        boolean res = false;
        try {
            res = fireCheckRecordPointGateway.add(fireCheckRecordPointE);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (!res) {
            throw new BizException("保存失败");
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    public FireCheckRecordPointCO saveCheckRecordPoint(AppCheckRecordPointAddCmd appCheckRecordPointAddCmd) {
        if (CollUtil.isEmpty(appCheckRecordPointAddCmd.getFireCheckRecordDeviceAddCmdList())) {
            throw new BizException("消防设备检查信息不能为空");
        }

        // 检查表是否存在，检查记录表是否存在，检查点位是否存在
        List<FireDeviceDO> fireDeviceDOList = fireDeviceRepository.getDeviceListByFirePointId(appCheckRecordPointAddCmd.getFirePointId());
        if (CollUtil.isEmpty(fireDeviceDOList)) {
            throw new BizException("消防点位不存在消防设备");
        }

        FireCheckRecordE fireCheckRecordE = fireCheckRecordGateway.initCheckRecord(appCheckRecordPointAddCmd.getFireCheckId(), appCheckRecordPointAddCmd.getFireRecordId());
        if (fireCheckRecordE == null) {
            throw new BizException("消防点位检查不存在");
        }
        FireCheckRecordPointE fireCheckRecordPointE = new FireCheckRecordPointE();
        //检查点位记录是否存在
        if (appCheckRecordPointAddCmd.getId() == null) {
            //新增
            //查找点位信息
            FirePointDO firePointDo = firePointRepository.getInfoByUUId(appCheckRecordPointAddCmd.getFirePointId());
            if (firePointDo == null) {
                throw new BizException("消防点位不存在");
            }
            FirePointE firePointE = new FirePointE();
            BeanUtils.copyProperties(firePointDo, firePointE);

            BeanUtils.copyProperties(appCheckRecordPointAddCmd, fireCheckRecordPointE);
            fireCheckRecordPointE.initFireCheckRecordPoint(fireCheckRecordE, firePointE);
            fireCheckRecordPointE.setLongitude(appCheckRecordPointAddCmd.getLongitude());
            fireCheckRecordPointE.setLatitude(appCheckRecordPointAddCmd.getLatitude());
            fireCheckRecordPointE.setCheckedFlag(CheckFlagEnum.CHECK_FLAG_CHECKED.getCode());
            fireCheckRecordPointGateway.add(fireCheckRecordPointE);
        } else {
            //修改
            BeanUtils.copyProperties(appCheckRecordPointAddCmd, fireCheckRecordPointE);
            fireCheckRecordPointGateway.update(fireCheckRecordPointE);
        }
        //根据消防设备id查询消防设备信息
        Map<String, FireDeviceDO> fireDeviceDOMap = fireDeviceDOList.stream().collect(Collectors.toMap(FireDeviceDO::getFireDeviceId, Function.identity()));
        //获取所有的设备类型
        List<String> fireDeviceTypeList = fireDeviceDOList.stream().map(FireDeviceDO::getFireDeviceType).distinct().collect(Collectors.toList());

        List<FireCheckStandardDO> fireCheckStandardDOList = fireCheckStandardRepository.getCheckStandardList(fireDeviceTypeList);

        Map<String, List<String>> fireCheckListItemStatisticDOMap = fireCheckStandardDOList.stream()
                .collect(Collectors.groupingBy(
                        FireCheckStandardDO::getFireDeviceType,
                        Collectors.mapping(FireCheckStandardDO::getFireCheckStandardItem, Collectors.toList())
                ));

        appCheckRecordPointAddCmd.getFireCheckRecordDeviceAddCmdList().forEach(fireCheckRecordDeviceAddCmd -> {
            FireCheckRecordDeviceE fireCheckRecordDeviceE = new FireCheckRecordDeviceE();

            if (fireCheckRecordDeviceAddCmd.getId() == null) {
                //新增
                FireDeviceDO fireDeviceDO = fireDeviceDOMap.get(fireCheckRecordDeviceAddCmd.getFireDeviceId());
                if (fireDeviceDO == null) {
                    throw new BizException("消防设备不存在");
                }
                FireDeviceE fireDeviceE = new FireDeviceE();
                BeanUtils.copyProperties(fireDeviceDO, fireDeviceE);
                fireCheckRecordDeviceE.initFireCheckRecordDevice(fireCheckRecordPointE, fireDeviceE);
                fireCheckRecordDeviceE.setLongitude(fireCheckRecordDeviceAddCmd.getLongitude());
                fireCheckRecordDeviceE.setLatitude(fireCheckRecordDeviceAddCmd.getLatitude());
                fireCheckRecordDeviceE.setNormalFlag(fireCheckRecordDeviceAddCmd.getNormalFlag());
                fireCheckRecordDeviceE.setCheckedFlag(CheckFlagEnum.CHECK_FLAG_CHECKED.getCode());
                fireCheckRecordDeviceE.setFireCheckStandardInfo(JSONUtil.toJsonStr(fireCheckListItemStatisticDOMap.get(fireDeviceE.getFireDeviceType())));
                fireCheckRecordDeviceGateway.add(fireCheckRecordDeviceE);

                //有隐患就新增
                if(CheckRecordNormalFlagEnum.NORMAL_FLAG_NOT_NORMAL.getCode().equals(fireCheckRecordDeviceE.getCheckedFlag()) && fireCheckRecordDeviceAddCmd.getHiddenAddCmd()==null){
                    throw new BizException("隐患信息不能为空");
                }
                if(fireCheckRecordDeviceAddCmd.getHiddenAddCmd()!=null){
                    HiddenAddCmd hiddenAddCmd = fireCheckRecordDeviceAddCmd.getHiddenAddCmd();
                    hiddenAddCmd.setForeignKey(fireCheckRecordE.getFireRecordId());
                    fireCheckRecordHiddenGateway.addHidden( fireCheckRecordDeviceE,hiddenAddCmd);
                }
            } else {
                //修改
                FireCheckRecordDeviceDO fireCheckRecordDeviceDO = fireCheckRecordDeviceRepository.getById(fireCheckRecordDeviceAddCmd.getId());
                if(fireCheckRecordDeviceDO==null){
                    throw new BizException("消防设备检查信息不存在");
                }
                BeanUtils.copyProperties(fireCheckRecordDeviceAddCmd, fireCheckRecordDeviceE);
                fireCheckRecordDeviceE.setFireCheckStandardInfo(JSONUtil.toJsonStr(fireCheckListItemStatisticDOMap.get(fireCheckRecordDeviceDO.getFireDeviceType())));

                fireCheckRecordDeviceGateway.update(fireCheckRecordDeviceE);
                if(fireCheckRecordDeviceE.getNormalFlag()==null){
                    //手动更新结果为null,因为有未排查记录的为null
                    fireCheckRecordDeviceRepository.updateNormalNull(fireCheckRecordDeviceAddCmd.getId());
                }
                //隐患是否更新
                FireCheckRecordHiddenDO fireCheckRecordHiddenDO = fireCheckRecordHiddenRepository.listByFireCheckRecordDeviceId(fireCheckRecordDeviceDO.getFireRecordDeviceId());

                if(CheckRecordNormalFlagEnum.NORMAL_FLAG_NOT_NORMAL.getCode().equals(fireCheckRecordDeviceE.getNormalFlag())){
                    //修改隐患信息
                    //根据消防设备id查询隐患信息
                    if(fireCheckRecordHiddenDO==null){
                        HiddenAddCmd hiddenAddCmd = fireCheckRecordDeviceAddCmd.getHiddenAddCmd();
                        hiddenAddCmd.setForeignKey(fireCheckRecordE.getFireRecordId());
                        FireCheckRecordDeviceE fireCheckRecordDeviceEOld = new FireCheckRecordDeviceE();
                        BeanUtils.copyProperties(fireCheckRecordDeviceDO, fireCheckRecordDeviceEOld);
                        fireCheckRecordHiddenGateway.addHidden( fireCheckRecordDeviceEOld,hiddenAddCmd);
                    }else{
                        FireCheckRecordHiddenE fireCheckRecordHiddenE = new FireCheckRecordHiddenE();
                        BeanUtils.copyProperties(fireCheckRecordHiddenDO, fireCheckRecordHiddenE);
                        HiddenAddCmd hiddenAddCmd = fireCheckRecordDeviceAddCmd.getHiddenAddCmd();
                        hiddenAddCmd.setForeignKey(fireCheckRecordE.getFireRecordId());
                        fireCheckRecordHiddenGateway.updateHidden(fireCheckRecordHiddenE,hiddenAddCmd);
                    }
                }else{
                    //删除隐患
                    if(fireCheckRecordHiddenDO!=null){
                        fireCheckRecordHiddenRepository.deletedFireCheckRecordHiddenById(fireCheckRecordHiddenDO);
                    }
                }
            }
        });

        FireCheckRecordPointCO fireCheckRecordPointCO = new FireCheckRecordPointCO();
        BeanUtils.copyProperties(fireCheckRecordPointE, fireCheckRecordPointCO);
        return fireCheckRecordPointCO;
    }
}

