package com.yeejoin.amos.boot.module.statistcs.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.statistics.api.mapper.AlertStatisticsMapper;
import com.yeejoin.amos.boot.module.statistics.api.mapper.CommonBaseMapper;
import com.yeejoin.amos.boot.module.ymt.api.dto.*;
import com.yeejoin.amos.boot.module.ymt.api.entity.*;
import com.yeejoin.amos.boot.module.ymt.api.enums.DispatchPaperEnums;
import com.yeejoin.amos.boot.module.ymt.api.enums.TzsCommonParam;
import com.yeejoin.amos.boot.module.ymt.api.mapper.*;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.RegionModel;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.DateUtil;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import static com.alibaba.fastjson.JSON.parseArray;
import static com.yeejoin.amos.boot.module.statistcs.biz.utils.JsonUtils.getJsonData;

@Service
public class EmergencyBizServiceImpl {

    @Value("classpath:/json/emergencyInformation.json")
    private Resource emergencyInformation;

    @Value("classpath:/json/emergencyBasic.json")
    private Resource emergencyBasic;

    @Value("classpath:/json/dispatchRecordFirst.json")
    private Resource dispatchRecordFirst;

    @Value("classpath:/json/dispatchRecordSecond.json")
    private Resource dispatchRecordSecond;

    @Value("classpath:/json/dispatchRecordPower.json")
    private Resource dispatchRecordPower;

    @Value("classpath:/json/rescueFollow.json")
    private Resource rescueFollowJson;

    @Value("classpath:/json/repairFollow.json")
    private Resource repairFollowJson;

    @Value("${redis.cache.failure.time:10800}")
    private long time;

    @Autowired
    public EmergencyBizServiceImpl(AlertStatisticsMapper alertStatisticsMapper,
                                   AlertCalledMapper alertCalledMapper,
                                   RepairConsultMapper repairConsultMapper,
                                   AlertFormValueMapper alertFormValueMapper,
                                   VoiceRecordFileMapper voiceRecordFileMapper,
                                   RescueProcessMapper rescueProcessMapper, DataDictionaryServiceImpl dataDictionaryService, CommonBaseMapper commonMapper, RescueStationMapper rescueStationMapper, DispatchTaskMapper dispatchTaskMapper, DispatchPaperMapper dispatchPaperMapper, ElevatorMapper elevatorMapper, RedisUtils redisUtils) {
        this.alertStatisticsMapper = alertStatisticsMapper;
        this.alertCalledMapper = alertCalledMapper;
        this.repairConsultMapper = repairConsultMapper;
        this.alertFormValueMapper = alertFormValueMapper;
        this.voiceRecordFileMapper = voiceRecordFileMapper;
        this.rescueProcessMapper = rescueProcessMapper;
        this.dataDictionaryService = dataDictionaryService;
        this.commonMapper = commonMapper;
        this.rescueStationMapper = rescueStationMapper;
        this.dispatchTaskMapper = dispatchTaskMapper;
        this.dispatchPaperMapper = dispatchPaperMapper;
        this.elevatorMapper = elevatorMapper;
        this.redisUtils = redisUtils;
    }

    private final AlertStatisticsMapper alertStatisticsMapper;
    private final AlertCalledMapper alertCalledMapper;
    private final RepairConsultMapper repairConsultMapper;
    private final AlertFormValueMapper alertFormValueMapper;
    private final VoiceRecordFileMapper voiceRecordFileMapper;
    private final RescueProcessMapper rescueProcessMapper;
    private final DataDictionaryServiceImpl dataDictionaryService;
    private final CommonBaseMapper commonMapper;
    private final RescueStationMapper rescueStationMapper;
    private final DispatchTaskMapper dispatchTaskMapper;
    private final DispatchPaperMapper dispatchPaperMapper;
    private final ElevatorMapper elevatorMapper;
    private final RedisUtils redisUtils;
    private static final Map<String, String> regionCodeOrgCodeMap = new ConcurrentHashMap<>();

    public Object getDetail(Long id) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        HashMap<String, Object> keyinfoData = new HashMap<>();
        // 基本信息
        List<FormValue> jsonData = getJsonData(emergencyInformation);
        AlertCalledFormDto alertCalledFormVo = getAlertCalledFormDto(id);
        Map<String, Object> objectMap = Bean.BeantoMap(alertCalledFormVo.getAlertCalledDto());
        List<FormValue> dynamicFormAlert = alertCalledFormVo.getDynamicFormAlert();
        jsonData.forEach(f -> {
            Object o = objectMap.get(f.getKey());
            if (!ObjectUtils.isEmpty(o)) {
                f.setValue(o.toString());
                if ("callTime".equals(f.getKey())) {
                    f.setValue(simpleDateFormat.format(alertCalledFormVo.getAlertCalledDto().getCallTime()));
                }
            }
        });
        jsonData.addAll(dynamicFormAlert);
        // 使用单位信息
        // 获取根据警情获取电梯信息
        Map<String, Object> map = this.selectByAlertId(id);
        // 根据设备id 获取使用单位信息
        Map<String, Object> useUnitMap = alertStatisticsMapper.selectUseUnitByAlertId(String.valueOf(map.get("sequenceNbr")));
        if (!ObjectUtils.isEmpty(useUnitMap)) {
            jsonData.forEach(f -> {
                // 单位名称
                if ("useUnitName".equals(f.getKey())) {
                    f.setValue(ObjectUtils.isEmpty(useUnitMap.get("useUnitName")) ? null : String.valueOf(useUnitMap.get("useUnitName")));
                }
                // 单位地址
                if ("unitAddress".equals(f.getKey())) {
                    f.setValue(ObjectUtils.isEmpty(useUnitMap.get("address")) ? null : String.valueOf(useUnitMap.get("address")));
                }
                // 安全管理员
                if ("securityAdministrator".equals(f.getKey())) {
                    f.setValue(ObjectUtils.isEmpty(useUnitMap.get("manager")) ? null : String.valueOf(useUnitMap.get("manager")));
                }
                // 安全管理员电话
                if ("securityAdministratorPhone".equals(f.getKey())) {
                    f.setValue(ObjectUtils.isEmpty(useUnitMap.get("managerPhone")) ? null : String.valueOf(useUnitMap.get("managerPhone")));
                }
            });
        }
        // 处置记录
        LambdaQueryWrapper<RepairConsult> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RepairConsult::getParentId, id).orderByDesc(RepairConsult::getRecDate);
        List<RepairConsult> list = repairConsultMapper.selectList(queryWrapper);
        HashMap<String, Object> datas = new HashMap<>();
        ArrayList<Map<String, Object>> records = new ArrayList<>();
        list.forEach(r -> {
            HashMap<String, Object> data = new HashMap<>();
            data.put("label", r.getAlertStatus());
            data.put("operatingTime", r.getRecDate());
            data.put("operater", r.getDescription());
            records.add(data);
        });
        // 96333码
        HashMap<String, Object> qrcode = new HashMap<>();
        if (!ObjectUtils.isEmpty(alertCalledFormVo.getAlertCalledDto())) {
            qrcode.put("title", "96333码");
            qrcode.put("value", alertCalledFormVo.getAlertCalledDto().getDeviceId());
            try {
                String problemTime = DateUtil.formatDate(new Date(), DateUtil.Y_M_D_HMS);
                qrcode.put("text", DateUtil.formatDate(DateUtil.smartFormat(problemTime), "yyyy-MM-dd"));
                qrcode.put("subtext", DateUtil.formatDate(DateUtil.smartFormat(problemTime), "HH:mm:ss"));
                String color;
                if (alertCalledFormVo.getAlertCalledDto().getAlertStatus()) {
                    color = "green";
                } else {
                    color = "red";
                }
                qrcode.put("color", color);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        datas.put("datas", records);
        datas.put("title", "处置记录");
        datas.put("renderType", "timeline");
        keyinfoData.put("title", ObjectUtils.isEmpty(useUnitMap.get("useUnitName")) ? null : String.valueOf(useUnitMap.get("useUnitName")));
        keyinfoData.put("keyParams", jsonData);
        keyinfoData.put("infoRecords", datas);
        keyinfoData.put("qrcode", qrcode);
        return keyinfoData;
    }

    public AlertCalledFormDto getAlertCalledFormDto(Long id) {
        // 警情基本信息
        AlertCalled alertCalled = alertCalledMapper.selectById(id);
        LambdaQueryWrapper<AlertFormValue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlertFormValue::getAlertCalledId, id);
        // 警情动态表单数据
        List<AlertFormValue> list = alertFormValueMapper.selectList(queryWrapper);
        List<FormValue> formValue = new ArrayList<FormValue>();
        if (list != null && !list.isEmpty()) {
            for (AlertFormValue alertFormValue : list) {
                FormValue value = new FormValue(alertFormValue.getFieldCode(), alertFormValue.getFieldName(), "text", alertFormValue.getFieldValue(), alertFormValue.getBlock());
                formValue.add(value);
            }
        }
        AlertCalledDto alertCalledDto = new AlertCalledDto();
        BeanUtils.copyProperties(alertCalled, alertCalledDto);
        Elevator elevator = new Elevator();
        elevator.setRescueCode(Integer.valueOf(alertCalled.getDeviceId()));
        elevator.setRegisterCode(alertCalled.getRegistrationCode());
        Map<String, Object> map = alertStatisticsMapper.selectElevator(elevator);
        if (!ObjectUtils.isEmpty(map)) {
            alertCalledDto.setAddress(String.valueOf(map.get("address")));
            alertCalledDto.setProvince(String.valueOf(map.get("province")));
            alertCalledDto.setCity(String.valueOf(map.get("city")));
            alertCalledDto.setDistrict(String.valueOf(map.get("district")));
            alertCalledDto.setUseStatus(Integer.valueOf(String.valueOf(map.get("useStatus"))));
            alertCalledDto.setUseSiteCategory(ObjectUtils.isEmpty(map.get("useSiteCategory")) || "null".equals(String.valueOf(map.get("useSiteCategory"))) ? null : String.valueOf(map.get("useSiteCategory")));
            alertCalledDto.setUseUnit(String.valueOf(map.get("useUnit")));
            alertCalledDto.setRegionCode(String.valueOf(map.get("regionCode")));
        }

        String voiceRecord = "";
        VoiceRecordFile temp = voiceRecordFileMapper.selectOne(new LambdaQueryWrapper<VoiceRecordFile>().eq(VoiceRecordFile::getAlertId, id).eq(VoiceRecordFile::getAlertStageCode, "860").orderByAsc(VoiceRecordFile::getTelStartTime).last("limit 1"));
        if (temp != null) {
            voiceRecord = temp.getFilePath();
        }
        return new AlertCalledFormDto(alertCalledDto, formValue, voiceRecord);
    }

    public Map<String, Object> selectByAlertId(Long alertId) {
        AlertCalled alertCalled = alertCalledMapper.selectById(alertId);
        if (ValidationUtil.isEmpty(alertCalled)
                || ValidationUtil.isEmpty(alertCalled.getDeviceId())) {
            throw new BadRequest("警情不存在或者设备编码不存在");
        }
        // 设备类型 和 编码 确定设备的使用单位或者维保单位
        String deviceId = String.valueOf(alertCalled.getEquipmentId());
        // 目前只有电梯类型
        Elevator elevator = new Elevator();
        elevator.setOriginalId(deviceId);
        Map<String, Object> map = alertStatisticsMapper.selectElevator(elevator);
        if (ValidationUtil.isEmpty(map)) {
            throw new BadRequest("设备未找到");
        }
        return map;
    }

    public Object getBasicDetail(Long id) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        HashMap<String, Object> map = new HashMap<>();
        List<FormValue> jsonData = getJsonData(emergencyBasic);
        RescueProcessDto dto = this.getProcessByAlertId(id);
        Map<String, Object> objectMap = Bean.BeantoMap(dto);
        jsonData.forEach(f -> {
            Object o = objectMap.get(f.getKey());
            if (!ObjectUtils.isEmpty(o)) {
                f.setValue(o.toString());
            }
            // 派遣状态
            if ("dispatchStatus".equals(f.getKey())) {
                if (Boolean.TRUE.equals(dto.getDispatchStatus())) {
                    f.setValue("已通知已派遣");
                } else {
                    f.setValue("未通知未派遣");
                }
            }
            // 到达状态
            if ("arriveStatus".equals(f.getKey())) {
                if (Boolean.TRUE.equals(dto.getArriveStatus())) {
                    f.setValue("已到达");
                } else {
                    f.setValue("未到达");
                }
            }
            // 伤亡状态
            if ("casualtiesStatus".equals(f.getKey())) {
                if (Boolean.TRUE.equals(dto.getCasualtiesStatus())) {
                    f.setValue("出现伤亡");
                } else {
                    f.setValue("未出现伤亡");
                }
            }
            // 救援状态
            if ("rescueStatus".equals(f.getKey())) {
                if (Boolean.TRUE.equals(dto.getRescueStatus())) {
                    f.setValue("救援成功");
                } else {
                    f.setValue("未救援成功");
                }
            }
            // 是否超时
            if ("isTimeout".equals(f.getKey())) {
                if (Boolean.TRUE.equals(dto.getIsTimeout())) {
                    f.setValue("是");
                } else {
                    f.setValue("否");
                }
            }
            // 派遣时间
            if ("dispatchTime".equals(f.getKey()) && !ObjectUtils.isEmpty(dto.getDispatchTime())) {
                f.setValue(simpleDateFormat.format(dto.getDispatchTime()));
            }
            // 到达时间
            if ("arriveTime".equals(f.getKey()) && !ObjectUtils.isEmpty(dto.getArriveTime())) {
                f.setValue(simpleDateFormat.format(dto.getArriveTime()));
            }
            // 完成时间
            if ("rescueTime".equals(f.getKey()) && !ObjectUtils.isEmpty(dto.getRescueTime())) {
                f.setValue(simpleDateFormat.format(dto.getRescueTime()));
            }

        });
        map.put("datas", jsonData);
        map.put("columns", 2);
        return map;
    }

    public RescueProcessDto getProcessByAlertId(Long alertId) {
        // 先通过id 查找过程表
        RescueProcessDto rescueProcessDto = new RescueProcessDto();
        QueryWrapper<RescueProcess> templateQueryWrapper = new QueryWrapper<>();
        templateQueryWrapper.eq("alert_id", alertId);
        RescueProcess rescueProcess = rescueProcessMapper.selectOne(templateQueryWrapper);
        Bean.toModel(rescueProcess, rescueProcessDto);
        // 到达时长 不超过30分钟为否，超过为是
        // 到达时长 救援响应人员到达时间—救援派遣成功时间
        //判断是否存在到达时间
        Date dispatchTime = rescueProcessDto.getDispatchTime();
        Date arriveTime = rescueProcessDto.getArriveTime();
        Date rescueTime = rescueProcessDto.getRescueTime();
        if (arriveTime != null && dispatchTime != null) {
            long arriveTimes = arriveTime.getTime() - dispatchTime.getTime(); // 相差毫秒数
            rescueProcessDto.setIsTimeout(arriveTimes >= 1800000);
        }
        // 救援时长  用到达时间减去派遣时间
        if (dispatchTime != null && arriveTime != null) {
            String hms = DateUtils.getTimeDiffString(arriveTime, dispatchTime);
            rescueProcessDto.setArriveUseTime(hms);
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        if (dispatchTime != null) rescueProcessDto.setDispatchTimeStr(sdf.format(dispatchTime));
        if (arriveTime != null) rescueProcessDto.setArriveTimeStr(sdf.format(arriveTime));
        if (rescueTime != null) rescueProcessDto.setRescueTimeStr(sdf.format(rescueTime));
        return rescueProcessDto;
    }

    public Object getDispatchRecord(Long id) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        HashMap<String, Object> result = new HashMap<>();
        ArrayList<Map<String, Object>> group = new ArrayList<>();
        String json;
        try {
            json = IOUtils.toString(dispatchRecordFirst.getInputStream(), String.valueOf(StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        List<Map> columns = parseArray(json, Map.class);
        // 一级调派
        // 获取根据警情获取电梯信息
        Map<String, Object> map = this.selectByAlertId(id);
        if (ObjectUtils.isEmpty(map)) {
            throw new BadRequest("设备未找到");
        }
        // 根据设备使用id 获取维保单位信息
        HashMap<String, Object> first = new HashMap<>();
        ArrayList<Map> firstDatas = new ArrayList<>();
        HashMap<String, Object> firstData = new HashMap<>();
        first.put("key", "firstLevelDispatch");
        first.put("renderType", "table");
        first.put("columns", columns);
        first.put("displayName", "一级调派");
        List<Map<String, Object>> list = alertStatisticsMapper.selectMtByAlertId(String.valueOf(map.get("sequenceNbr")));
        firstDatas.add(firstData);
        first.put("dataList", list);
        first.put("rowKey", "sequenceNbr");
        // 二级调派
        String secondJson;
        try {
            secondJson = IOUtils.toString(dispatchRecordSecond.getInputStream(), String.valueOf(StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        List<Map> secondColumns = parseArray(secondJson, Map.class);
        // 获取根据警情获取电梯信息
        Map<String, Object> map2 = this.selectByAlertId(id);
        String longitude = String.valueOf(map2.get("longitude"));
        String latitude = String.valueOf(map2.get("latitude"));
        // 根据经纬度和距离返回救援机构信息
        HashMap<String, Object> second = new HashMap<>();
        second.put("key", "secondLevelDispatch");
        second.put("renderType", "table");
        second.put("columns", secondColumns);
        second.put("displayName", "二级调派");
        List<RescueStationDto> listByLatLonDistance = rescueStationMapper.getListByLatLonDistance(latitude, longitude, 1000);
        second.put("dataList", listByLatLonDistance);
        second.put("rowKey", "sequenceNbr");
        // 力量调派
        String powerJson;
        try {
            powerJson = IOUtils.toString(dispatchRecordPower.getInputStream(), String.valueOf(StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        List<Map> powerColumns = parseArray(powerJson, Map.class);
        LambdaQueryWrapper<DispatchTask> queryWrapper = new LambdaQueryWrapper<DispatchTask>();
        queryWrapper.eq(DispatchTask::getAlertId, id);
        HashMap<String, Object> power = new HashMap<>();
        ArrayList<Map> powerDatas = new ArrayList<>();
        power.put("key", "powerLevelDispatch");
        power.put("renderType", "table");
        power.put("columns", powerColumns);
        power.put("displayName", "使用单位");
        List<DispatchTask> powerList = dispatchTaskMapper.selectList(queryWrapper);
        if (!ObjectUtils.isEmpty(powerList)) {
            powerList.forEach(p -> {
                Map<String, Object> objectMap = Bean.BeantoMap(p);
                if (!ObjectUtils.isEmpty(p.getDispatchTime())) {
                    objectMap.put("dispatchTime", simpleDateFormat.format(p.getDispatchTime()));
                }
                if (!ObjectUtils.isEmpty(p.getArriveTime())) {
                    objectMap.put("arriveTime", simpleDateFormat.format(p.getArriveTime()));
                }
                powerDatas.add(objectMap);
            });
        }
        power.put("dataList", powerDatas);
        power.put("rowKey", "sequenceNbr");
        group.add(power);
        group.add(first);
        group.add(second);
        result.put("subs", group);
        return result;
    }

    public Object getFollowRecords(Long id) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        HashMap<String, Object> result = new HashMap<>();
        ArrayList<Map<String, Object>> group = new ArrayList<>();
        DispatchSaveFeedbackDto dispatchSaveFeedbackDto = this.getDispatchSaveFeedbackDtoByAlertId(id);
        Map<String, Object> objectMap = Bean.BeantoMap(dispatchSaveFeedbackDto);
        // 救援回访
        HashMap<String, Object> rescueFollow = new HashMap<>();
        List<FormValue> jsonData = getJsonData(rescueFollowJson);
        jsonData.forEach(formValue -> {
            Object o = objectMap.get(formValue.getKey());
            if (!ObjectUtils.isEmpty(o)) {
                formValue.setValue(o.toString());
                if ("saveFeedbackTime".equals(formValue.getKey())) {
                    formValue.setValue(simpleDateFormat.format(dispatchSaveFeedbackDto.getSaveFeedbackTime()));
                }
            }
        });
        rescueFollow.put("columns", 2);
        rescueFollow.put("datas", jsonData);
        rescueFollow.put("renderType", "basic");
        rescueFollow.put("key", "rescueFollow");
        rescueFollow.put("displayName", "救援回访");
        group.add(rescueFollow);
        // 维修反馈
        HashMap<String, Object> repairFollow = new HashMap<>();
        List<FormValue> repairJson = getJsonData(repairFollowJson);
        repairJson.forEach(f -> {
            Object o = objectMap.get(f.getKey());
            if (!ObjectUtils.isEmpty(o)) {
                f.setValue(o.toString());
                if ("feedbackFinishTime".equals(f.getKey())) {
                    f.setValue(simpleDateFormat.format(dispatchSaveFeedbackDto.getFeedbackFinishTime()));
                }
                if ("fixResult".equals(f.getKey())) {
                    f.setValue(dataDictionaryService.getById(dispatchSaveFeedbackDto.getFixResult()).getName());
                }
                if ("errorResult".equals(f.getKey())) {
                    f.setValue(dataDictionaryService.getById(dispatchSaveFeedbackDto.getErrorResult()).getName());
                }
            }
        });
        repairFollow.put("columns", 2);
        repairFollow.put("datas", repairJson);
        repairFollow.put("renderType", "basic");
        repairFollow.put("key", "repairFollow");
        repairFollow.put("displayName", "维修反馈");
        group.add(repairFollow);
        result.put("subs", group);
        return result;
    }

    public Object getCallRecords(Long id, int number, int size) {
        Page<VoiceRecordFileDto> voiceRecordFileDtoPage = new Page<>();
        HashMap<String, Object> map = new HashMap<>();
        LambdaQueryWrapper<VoiceRecordFile> queryWrapper = new LambdaQueryWrapper<VoiceRecordFile>();
        queryWrapper.eq(VoiceRecordFile::getAlertId, id).orderByDesc(VoiceRecordFile::getRecDate);
        List<VoiceRecordFile> list = voiceRecordFileMapper.selectList(queryWrapper);
        List<VoiceRecordFileDto> dtoList = new ArrayList<>(list.size());
        list.forEach(voiceRecord -> {
            // 创建新的对象实例
            VoiceRecordFileDto target = new VoiceRecordFileDto();
            // 把原对象数据拷贝到新对象
            BeanUtils.copyProperties(voiceRecord, target);
            dtoList.add(target);
        });
        List<VoiceRecordFileDto> collect = dtoList.stream()
                .skip((long) (number - 1) * size)
                .limit(size)
                .collect(Collectors.toList());
        voiceRecordFileDtoPage.setRecords(collect);
        voiceRecordFileDtoPage.setCurrent(number);
        voiceRecordFileDtoPage.setSize(size);
        return voiceRecordFileDtoPage;
    }

    public Page<AlertCalledQueryDto> getAlertCalledRecords(Page<AlertCalledQueryDto> page, AlertCalledQueryDto alertCalledQueryDto, String cityCode) {
        String orgCode = getAndSetOrgCode(cityCode);
        return alertStatisticsMapper.getAlertCalledRecords(page, alertCalledQueryDto, orgCode);
    }

    public String getAndSetOrgCode(String cityCode) {
        String orgCode = regionCodeOrgCodeMap.get(cityCode);
        if (orgCode == null) {
            orgCode = commonMapper.getOrgCodeByCompanyCode(cityCode);
            if (orgCode != null) {
                regionCodeOrgCodeMap.put(cityCode, orgCode);
            }
        }
        return orgCode;
    }

    public DispatchSaveFeedbackDto getDispatchSaveFeedbackDtoByAlertId(Long alertId) {
        DispatchSaveFeedbackDto dispatchSaveFeedbackDto = new DispatchSaveFeedbackDto();
        dispatchSaveFeedbackDto.setAlertId(alertId);
        AlertCalledFormDto alertCalledFormVo = this.selectAlertCalledByIdNoCache(alertId);
        // 警情信息
        AlertCalledDto alertCalledDto = alertCalledFormVo.getAlertCalledDto();
        dispatchSaveFeedbackDto.setEmergency(alertCalledDto.getEmergencyPerson());
        dispatchSaveFeedbackDto.setEmergencyCall(alertCalledDto.getEmergencyCall());
        // 派遣单信息
        DispatchPaperFormDto dispatchPaperFormDto = this.selectDispatchPaperDtoByAlertId(alertId);
        if (dispatchPaperFormDto == null || dispatchPaperFormDto.getDispatchPaper() == null) {
            return new DispatchSaveFeedbackDto(); // 如果没有派遣就没有派遣反馈信息
        }
        DispatchPaper dispatchPaper = dispatchPaperFormDto.getDispatchPaper();
        dispatchSaveFeedbackDto.setFeedbackFinishTime(dispatchPaper.getFeedbackFinishTime());
        if (StringUtils.isBlank(dispatchPaper.getFeedbackUid())) {
            dispatchSaveFeedbackDto.setFeedbackUid(null);
        } else {
            dispatchSaveFeedbackDto.setFeedbackUid(dispatchPaper.getFeedbackUid());
        }
        if (StringUtils.isBlank(dispatchPaper.getFeedbackUname())) {
            dispatchSaveFeedbackDto.setFeedbackUname(null);
        } else {
            dispatchSaveFeedbackDto.setFeedbackUname(dispatchPaper.getFeedbackUname());
        }

        //救援响应人和维保响应人
        Long useOrgTaskId = dispatchPaper.getUseOrgTaskId();
        Long repairOrgTaskId = dispatchPaper.getRepairOrgTaskId();

        // 如果维保单位和使用单位都下单了 默认显示维保单位
        DispatchTask dispatchTask;
        if (repairOrgTaskId != null) {
            dispatchTask = dispatchTaskMapper.selectById(repairOrgTaskId);
            dispatchSaveFeedbackDto.setResponseUserName(dispatchTask.getResponseUserName());
            dispatchSaveFeedbackDto.setResponseUserTel(dispatchTask.getResponseUserTel());
        } else if (useOrgTaskId != null) {
            dispatchTask = dispatchTaskMapper.selectById(useOrgTaskId);
            dispatchSaveFeedbackDto.setResponseUserName(dispatchTask.getResponseUserName());
            dispatchSaveFeedbackDto.setResponseUserTel(dispatchTask.getResponseUserTel());
        }
        // 动态字段
        List<AlertFormValue> dynamicFormAlert = dispatchPaperFormDto.getDynamicFormAlert();
        dynamicFormAlert.forEach(alertFormValue -> {
            String value = null;
            switch (alertFormValue.getFieldCode()) {
                case TzsCommonParam.SAVE_FEEDBACK_TIME:
                    value = alertFormValue.getFieldValue();
                    if (StringUtils.isBlank(value)) {
                        dispatchSaveFeedbackDto.setSaveFeedbackTime(null);
                    } else {
                        try {
                            dispatchSaveFeedbackDto.setSaveFeedbackTime(DateUtils.longStr2Date(value));
                        } catch (Exception e) {
                            throw new BadRequest("救援时间格式错误");
                        }
                    }
                    break;
                case TzsCommonParam.SAVE_FEEDBACK_USER:
                    value = alertFormValue.getFieldValue();
                    if (StringUtils.isBlank(value)) {
                        dispatchSaveFeedbackDto.setSaveFeedbackUser(null);
                    } else {
                        dispatchSaveFeedbackDto.setSaveFeedbackUser(value);
                    }
                    break;
                case TzsCommonParam.SAVE_FEEDBACK_UID:
                    value = alertFormValue.getFieldValue();
                    if (StringUtils.isBlank(value)) {
                        dispatchSaveFeedbackDto.setSaveFeedbackUid(null);
                    } else {
                        dispatchSaveFeedbackDto.setSaveFeedbackUid(value);
                    }
                    break;
                case TzsCommonParam.SAVE_FEEDBACK_RESULT:
                    value = alertFormValue.getFieldValue();
                    dispatchSaveFeedbackDto.setSaveFeedbackResult(value);
                    break;
                case TzsCommonParam.FIX_RESULT:
                    value = alertFormValue.getFieldValueCode();
                    dispatchSaveFeedbackDto.setFixResult(value);
                    break;
                case TzsCommonParam.ERROR_RESULT:
                    value = alertFormValue.getFieldValueCode();
                    dispatchSaveFeedbackDto.setErrorResult(value);
                    break;
                case TzsCommonParam.FIX_REMARK:
                    value = alertFormValue.getFieldValue();
                    dispatchSaveFeedbackDto.setFixRemark(value);
                    break;
                case TzsCommonParam.FIX_FEEDBACK_TYPE:// 保修反馈方式
                    value = alertFormValue.getFieldValueCode();
                    dispatchSaveFeedbackDto.setFeedbackCode(value);
                    dispatchSaveFeedbackDto.setFeedbackType(alertFormValue.getFieldValue());
                    break;
            }

        });

        return dispatchSaveFeedbackDto;
    }

    public AlertCalledFormDto selectAlertCalledByIdNoCache(Long id) {
        // 警情基本信息
        AlertCalled alertCalled = alertCalledMapper.selectById(id);
        LambdaQueryWrapper<AlertFormValue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlertFormValue::getAlertCalledId, id);
        // 警情动态表单数据
        List<AlertFormValue> list = alertFormValueMapper.selectList(queryWrapper);
        List<FormValue> formValue = new ArrayList<FormValue>();
        if (list != null && !list.isEmpty()) {
            for (AlertFormValue alertFormValue : list) {
                FormValue value = new FormValue(alertFormValue.getFieldCode(), alertFormValue.getFieldName(), "text", alertFormValue.getFieldValue(), alertFormValue.getBlock());
                formValue.add(value);
            }
        }
        AlertCalledDto alertCalledDto = new AlertCalledDto();
        BeanUtils.copyProperties(alertCalled, alertCalledDto);
        LambdaQueryWrapper<Elevator> elevatorQueryWrapper = new LambdaQueryWrapper<>();
        elevatorQueryWrapper.eq(Elevator::getRescueCode, alertCalled.getDeviceId());
        elevatorQueryWrapper.eq(Elevator::getRegisterCode, alertCalled.getRegistrationCode());
        Elevator elevator = elevatorMapper.selectOne(elevatorQueryWrapper);
        if (null != elevator) {
            alertCalledDto.setAddress(elevator.getAddress());
            alertCalledDto.setProvince(elevator.getProvince());
            alertCalledDto.setCity(elevator.getCity());
            alertCalledDto.setDistrict(elevator.getDistrict());
            alertCalledDto.setUseStatus(Integer.valueOf(String.valueOf(elevator.getUseStatus())));
            alertCalledDto.setUseSiteCategory(elevator.getUseSiteCategory());
            alertCalledDto.setUseUnit(elevator.getUseUnit());
            alertCalledDto.setRegionCode(elevator.getRegionCode());
        }
        String voiceRecord = "";
        return new AlertCalledFormDto(alertCalledDto, formValue, voiceRecord);
    }

    public DispatchPaperFormDto selectDispatchPaperDtoByAlertId(Long alertId) {
        // 根据警情id 获取 派遣单信息
        DispatchPaper dispatchPaper = selectDispatchPaperByAlertId(alertId);
        // 封装dto
        DispatchPaperFormDto dispatchPaperFormDto = new DispatchPaperFormDto();
        if (dispatchPaper == null) { //如果没有找到paper 返回空Dto
            return dispatchPaperFormDto;
        }
        dispatchPaperFormDto.setDispatchPaper(dispatchPaper);
        LambdaQueryWrapper<AlertFormValue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlertFormValue::getAlertCalledId, dispatchPaper.getSequenceNbr()).eq(AlertFormValue::getAlertTypeCode, DispatchPaperEnums.getEnumById(dispatchPaper.getAlertCode()).getDynamicCode());
        // 派遣单动态表单数据
        List<AlertFormValue> list = alertFormValueMapper.selectList(queryWrapper);
        dispatchPaperFormDto.setDynamicFormAlert(list);
        return dispatchPaperFormDto;
    }

    public DispatchPaper selectDispatchPaperByAlertId(Long alertId) {
        LambdaQueryWrapper<DispatchPaper> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DispatchPaper::getAlertId, alertId);
        // 警情动态表单数据
        return dispatchPaperMapper.selectOne(queryWrapper);
    }

    public VoiceRecordFileDto getRecordById(Long sequenceNbr) {
        return voiceRecordFileMapper.getRecordById(sequenceNbr);
    }

    public Object selectAlertCalledById(Long id) {
        if (redisUtils.hasKey(RedisKey.TZS_ALERTCALLED_ID + id)) {
            return redisUtils.get(RedisKey.TZS_ALERTCALLED_ID + id);
        }
        AlertCalledFormDto alertCalledFormVo = getAlertCalledFormDto(id);
        redisUtils.set(RedisKey.TZS_ALERTCALLED_ID + id, JSON.toJSON(alertCalledFormVo), time);
        return alertCalledFormVo;
    }

    public List<AlertPaperInfoDto> getAlertPaperInfoList(List<String> regionCodes, Boolean isHistory) {
        List<AlertPaperInfoDto> temp = alertStatisticsMapper.getAlertPaperInfoList(regionCodes, isHistory);
        temp.forEach(t -> {
            DispatchPaper paper = dispatchPaperMapper.selectOne(new LambdaQueryWrapper<DispatchPaper>().eq(DispatchPaper::getIsDelete,false).eq(DispatchPaper::getAlertId,t.getAlertId()));
            if(paper != null) {
                t.setFinishTime(paper.getFeedbackFinishTime());
            }
        });
        return temp;
    }

    public List<String> authRegionCodeList(List<String> regionCodes) {
        // 警情id 警情地址 警情状态 警情类型 警情发生时间
        List<String> useRegionCode = this.getUserRegionCode();
        if(regionCodes == null) {
            regionCodes = useRegionCode;
        } else {
            // 判断传入regionCodes 是否越权
            List<String> tempList = new ArrayList<>();
            Iterator<String> regionIt =  regionCodes.iterator();
            while(regionIt.hasNext()) {
                String tempCode = regionIt.next();
                String districtCode = tempCode.substring(4,6);
                String provinceCode = tempCode.substring(2,6);
                if("0000".equals(provinceCode)) {// 为省则默认使用用户现有权限查询数据
                    regionCodes = useRegionCode;
                } else {
                    if("00".equals(districtCode)) { // 为市
                        if(!useRegionCode.contains(tempCode)) { // 不包含该市权限 需要移除市搜索条件 添加 该市下区搜索条件
                            for(String tempUsercode : useRegionCode) {
                                if(tempUsercode.contains(tempCode.substring(0, 4))) {
                                    tempList.add(tempUsercode);
                                }
                            }
                            regionIt.remove();
                        }
                    } else { // 为区 不会出现越权情况

                    }
                }
            }
            regionCodes.addAll(tempList);
        }
        return regionCodes;
    }

    public List<String> getUserRegionCode() {
        List<String> regionList = new ArrayList<>();
        AgencyUserModel me = Privilege.agencyUserClient.getme().getResult();
        CompanyModel userCompany = me.getCompanys().get(0);
        String regions = userCompany.getRegionSeq();
        if(regions != null) {
            String[] regionsId = regions.split(",");
            for(String regionId:regionsId) {
                RegionModel region = Systemctl.regionClient.getRegion(Long.valueOf(regionId)).getResult();
                regionList.add(region.getRegionCode() + "");
            }
        }
        return regionList;
    }
}
