package com.tuoheng.admin.service.accident.build;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tuoheng.admin.conver.AccidentConverMapper;
import com.tuoheng.admin.entity.*;
import com.tuoheng.admin.enums.MarkEnum;
import com.tuoheng.admin.mapper.*;
import com.tuoheng.admin.request.accident.AccidentRegion;
import com.tuoheng.admin.vo.accident.AccidentVo;
import com.tuoheng.admin.vo.airport.AirPortStatusVO;
import com.tuoheng.common.core.config.common.CommonConfig;
import com.tuoheng.common.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 组装应急事故VO列表业务层处理
 *
 * @author wanjing
 * @team tuoheng
 * @date 2023-03-03
 */
@Slf4j
@Service
public class BuildAccidentVoListService {

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private InspectionMapper inspectionMapper;

    @Autowired
    private InspectionFileMapper inspectionFileMapper;

    @Autowired
    private AccidentInspectionMapper accidentInspectionMapper;

    @Autowired
    private AirportLineMapper airportLineMapper;

    @Autowired
    private LiveChannelMapper liveChannelMapper;


    /**
     * @param accidentList
     * @return
     */
    public List<AccidentVo> build(List<Accident> accidentList) {
        if (CollectionUtil.isEmpty(accidentList)) {
            return null;
        }
        Map<String, String> deptNameMap = this.getDeptMap(accidentList);
        Map<String, InspectionFile> inspectionFileMap = this.getInspectionFileMap(accidentList);
        Map<String, Inspection> inspectionMap = this.getInspectionMap(accidentList);
        List<AccidentInspection> accidentInspectionList = this.getAccidentInspectionList(accidentList);
        Map<String, AccidentInspection> accidentInspectionMap = this.getAccidentInspectionMap(accidentInspectionList);
        Map<String, Inspection> emergencyInspectionMap = this.getEmergencyInspectionMap(accidentInspectionList);
        Map<String, AirportLine> airportLineMap = this.getAirportLineMap(accidentList);

        Map<String, LiveChannel> liveChannelMap = this.getLiveChannelMap(accidentList, accidentInspectionList);

        List<AccidentVo> accidentVoList = AccidentConverMapper.INSTANCE.accidentListToAccidentVoList(accidentList);
        String deptName;
        AccidentInspection accidentInspection;
        InspectionFile inspectionFile;
        Inspection inspection;
        Inspection emergencyInspectionl;
        List<AccidentRegion> accidentRegionList;
        AccidentRegion accidentRegion;
        AirportLine airportLine;
        LiveChannel originalLiveChannel;
        LiveChannel emergencyLiveChannel;
        for (AccidentVo accidentVo : accidentVoList) {
            if (ObjectUtil.isNotNull(deptNameMap)) {
                deptName = deptNameMap.get(accidentVo.getDeptId());
                accidentVo.setDeptName(deptName);
            }
            if (CollectionUtil.isNotEmpty(accidentInspectionMap)) {
                accidentInspection = accidentInspectionMap.get(accidentVo.getId());
                if (ObjectUtil.isNotEmpty(accidentInspection)) {
                    accidentVo.setAccidentInspectionId(accidentInspection.getInspectionId());
                    accidentVo.setDroneForwardType(accidentInspection.getDroneForwardType());
                }
            }
            if (CollectionUtil.isNotEmpty(inspectionFileMap)) {
                inspectionFile = inspectionFileMap.get(accidentVo.getInspectionFileId());
                if (ObjectUtil.isNotEmpty(inspectionFile)) {
                    accidentVo.setFileName(inspectionFile.getFileName());
                    accidentVo.setFileImage(CommonConfig.imageURL + inspectionFile.getFileImage());
                    accidentVo.setFileOriginal(CommonConfig.imageURL + inspectionFile.getFileOriginal());
                    accidentVo.setFileThumbnail(CommonConfig.imageURL + inspectionFile.getFileThumbnail());
                }
            }
            if (CollectionUtil.isNotEmpty(inspectionMap)) {
                inspection = inspectionMap.get(accidentVo.getInspectionId());
                if (ObjectUtil.isNotEmpty(inspection)) {
                    accidentVo.setInspectionStatus(inspection.getStatus());
                    accidentVo.setOriginalInspectionVideoUrl(inspection.getVideoUrl());
                    accidentVo.setOriginalInspectionAiVideoUrl(inspection.getAiVideoUrl());
                }
            }
            if (CollectionUtil.isNotEmpty(emergencyInspectionMap)) {
                emergencyInspectionl = emergencyInspectionMap.get(accidentVo.getId());
                if (ObjectUtil.isNotEmpty(emergencyInspectionl)) {
                    accidentVo.setInspectionStatus(emergencyInspectionl.getStatus());
                    accidentVo.setEmergencyInspectionVideoUrl(emergencyInspectionl.getVideoUrl());
                    accidentVo.setEmergencyInspectionAiVideoUrl(emergencyInspectionl.getAiVideoUrl());
                }
            }
            accidentRegionList = new ArrayList<>();
            if (3 == accidentVo.getSource()) {
                if (CollectionUtil.isNotEmpty(airportLineMap)) {
                    airportLine = airportLineMap.get(accidentVo.getId());
                    if (ObjectUtil.isNotEmpty(airportLine)) {
                        accidentVo.setLineType(airportLine.getLineType());
                        if (StringUtils.isNotEmpty(airportLine.getAccidentRegion())) {
                            accidentRegionList = JSONObject.parseArray(airportLine.getAccidentRegion(), AccidentRegion.class);
                        }
                    }
                }
            } else {
                accidentVo.setLineType(1); // 1:巡检任务产生; 2:应急任务产生; 航线类型肯定是点
                accidentRegion = new AccidentRegion();
                accidentRegion.setLng(accidentVo.getLongitude());
                accidentRegion.setLat(accidentVo.getLatitude());
                accidentRegionList.add(accidentRegion);
            }
            accidentVo.setAccidentRegionList(accidentRegionList);

            if (CollectionUtil.isNotEmpty(liveChannelMap)) {
                if (ObjectUtil.isEmpty(accidentVo.getDroneForwardType())) {
                    // droneForwardType 为null的场景
                    originalLiveChannel = liveChannelMap.get(accidentVo.getInspectionId());
                    if (ObjectUtil.isNotEmpty(originalLiveChannel)) {
                        accidentVo.setOriginalInspectionPullUrl(originalLiveChannel.getPullUrl());
                        accidentVo.setOriginalInspectionAiPullUrl(originalLiveChannel.getAipullUrl());
                    }
                } else if (1 == accidentVo.getDroneForwardType()) {
                    originalLiveChannel = liveChannelMap.get(accidentVo.getInspectionId());
                    if (ObjectUtil.isNotEmpty(originalLiveChannel)) {
                        accidentVo.setOriginalInspectionPullUrl(originalLiveChannel.getPullUrl());
                        accidentVo.setOriginalInspectionAiPullUrl(originalLiveChannel.getAipullUrl());
                        accidentVo.setEmergencyInspectionPullUrl(originalLiveChannel.getPullUrl());
                        accidentVo.setEmergencyInspectionAiPullUrl(originalLiveChannel.getAipullUrl());
                    }
                } else if (2 == accidentVo.getDroneForwardType() || 3 == accidentVo.getDroneForwardType()) {
                    originalLiveChannel = liveChannelMap.get(accidentVo.getInspectionId());
                    if (ObjectUtil.isNotEmpty(originalLiveChannel)) {
                        accidentVo.setOriginalInspectionPullUrl(originalLiveChannel.getPullUrl());
                        accidentVo.setOriginalInspectionAiPullUrl(originalLiveChannel.getAipullUrl());
                    }
                    emergencyLiveChannel = liveChannelMap.get(accidentVo.getAccidentInspectionId());
                    if (ObjectUtil.isNotEmpty(emergencyLiveChannel)) {
                        accidentVo.setEmergencyInspectionPullUrl(emergencyLiveChannel.getPullUrl());
                        accidentVo.setEmergencyInspectionAiPullUrl(emergencyLiveChannel.getAipullUrl());
                    }
                }
            }
        }
        return accidentVoList;
    }

    private Map<String, Inspection> getInspectionMap(List<Accident> accidentList) {
        if (CollectionUtil.isEmpty(accidentList)) {
            return null;
        }
        List<String> inspectionIdList = accidentList.stream().map(o -> o.getInspectionId()).collect(Collectors.toList());
        List<Inspection> inspectionList = inspectionMapper.selectList(Wrappers.<Inspection>lambdaQuery()
                .eq(Inspection::getMark, MarkEnum.VALID.getCode())
                .in(Inspection::getId, inspectionIdList));
        Map<String, Inspection> inspectionMap = inspectionList.stream().collect(HashMap::new, (m, v) -> m.put(v.getId(), v), HashMap::putAll);

        return inspectionMap;
    }

    private List<AccidentInspection> getAccidentInspectionList(List<Accident> accidentList) {
        if (CollectionUtil.isEmpty(accidentList)) {
            return null;
        }
        List<String> accidentIdList = accidentList.stream().map(o -> o.getId()).collect(Collectors.toList());
        List<AccidentInspection> accidentInspectionList = accidentInspectionMapper.selectList(Wrappers.<AccidentInspection>lambdaQuery()
                .eq(AccidentInspection::getMark, MarkEnum.VALID.getCode())
                .in(AccidentInspection::getAccidentId, accidentIdList));
        if (CollectionUtil.isEmpty(accidentInspectionList)) {
            return null;
        }
        return accidentInspectionList;
    }


    private Map<String, AccidentInspection> getAccidentInspectionMap(List<AccidentInspection> accidentInspectionList) {
        if (CollectionUtil.isEmpty(accidentInspectionList)) {
            return null;
        }
        Map<String, AccidentInspection> accidentInspectionMap = accidentInspectionList.stream().collect(HashMap::new, (m, v) -> m.put(v.getAccidentId(), v), HashMap::putAll);
        return accidentInspectionMap;
    }

    private Map<String, Inspection> getEmergencyInspectionMap(List<AccidentInspection> accidentInspectionList) {
        if (CollectionUtil.isEmpty(accidentInspectionList)) {
            return null;
        }
        List<String> inspectionIdList = accidentInspectionList.stream().map(o -> o.getInspectionId()).collect(Collectors.toList());
        List<Inspection> inspectionList = inspectionMapper.selectList(Wrappers.<Inspection>lambdaQuery()
                .eq(Inspection::getMark, MarkEnum.VALID.getCode())
                .in(Inspection::getId, inspectionIdList));
        if (CollectionUtil.isEmpty(inspectionList)) {
            return null;
        }
        Map<String, Inspection> inspectionMapTmp = inspectionList.stream().collect(HashMap::new, (m, v) -> m.put(v.getId(), v), HashMap::putAll);
        Map<String, Inspection> inspectionMap = new HashMap<>();
        Inspection inspection;
        for (AccidentInspection accidentInspection : accidentInspectionList) {
            inspection = inspectionMapTmp.get(accidentInspection.getInspectionId());
            if (ObjectUtil.isNotNull(inspection)) {
                inspectionMap.put(accidentInspection.getAccidentId(), inspection);
            }
        }
        return inspectionMap;
    }

    /**
     * 设置列表中每一个的部门名称
     * 查询到的列表中的部门Id，作为部门id列表，查询所有的部门，该结果数据量不会太大，放到map中
     *
     * @param accidentList
     * @return
     */
    private Map<String, String> getDeptMap(List<Accident> accidentList) {
        if (CollectionUtil.isEmpty(accidentList)) {
            return null;
        }
        List<String> deptIdList = accidentList.stream().map(o -> o.getDeptId()).collect(Collectors.toList());
        List<Dept> deptList = deptMapper.selectListByIdList(deptIdList);
        Map<String, String> deptNameMap = deptList.stream().collect(HashMap::new, (m, v) -> m.put(v.getId(), v.getName()), HashMap::putAll);
        return deptNameMap;
    }

    private Map<String, InspectionFile> getInspectionFileMap(List<Accident> accidentList) {
        if (CollectionUtil.isEmpty(accidentList)) {
            return null;
        }
        List<String> inspectionFileIdList = accidentList.stream().map(o -> o.getInspectionFileId()).collect(Collectors.toList());
        List<InspectionFile> inspectionFileList = inspectionFileMapper.selectList(new LambdaQueryWrapper<InspectionFile>()
                .in(InspectionFile::getId, inspectionFileIdList));
        Map<String, InspectionFile> inspectionFileMap = inspectionFileList.stream().collect(HashMap::new, (m, v) -> m.put(v.getId(), v), HashMap::putAll);
        return inspectionFileMap;
    }

    private Map<String, AirportLine> getAirportLineMap(List<Accident> accidentList) {
        if (CollectionUtil.isEmpty(accidentList)) {
            return null;
        }
        List<String> accidentListIdList = accidentList.stream().map(o -> o.getId()).collect(Collectors.toList());
        List<AirportLine> airportLineList = airportLineMapper.selectList(new LambdaQueryWrapper<AirportLine>()
                .in(AirportLine::getAccidentId, accidentListIdList));
        Map<String, AirportLine> airportLineMap = airportLineList.stream().collect(HashMap::new, (m, v) -> m.put(v.getAccidentId(), v), HashMap::putAll);
        return airportLineMap;
    }

    private Map<String, LiveChannel> getLiveChannelMap(List<Accident> accidentList, List<AccidentInspection> accidentInspectionList) {
        List<String> inspectionIdList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(accidentList)) {
            inspectionIdList = accidentList.stream().map(o -> o.getInspectionId()).collect(Collectors.toList());
        }
        List<String> emergencyInspectionIdList = new ArrayList<>();;
        if (CollectionUtil.isNotEmpty(accidentInspectionList)) {
            emergencyInspectionIdList = accidentInspectionList.stream().map(o -> o.getInspectionId()).collect(Collectors.toList());
        }
        inspectionIdList.addAll(emergencyInspectionIdList);
        if (CollectionUtil.isEmpty(inspectionIdList)) {
            return null;
        }
        List<LiveChannel> liveChannelList = liveChannelMapper.selectList(new LambdaQueryWrapper<LiveChannel>()
                .in(LiveChannel::getInspectionId, inspectionIdList));
        Map<String, LiveChannel> liveChannelMap = liveChannelList.stream().collect(HashMap::new, (m, v) -> m.put(v.getInspectionId(), v), HashMap::putAll);
        return liveChannelMap;
    }

}
