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

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.module.tzs.api.dto.DispatchPaperFormDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.DispatchTaskDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.RescueProcessDto;
import com.yeejoin.amos.boot.module.tzs.api.entity.AlertFormValue;
import com.yeejoin.amos.boot.module.tzs.api.entity.DispatchPaper;
import com.yeejoin.amos.boot.module.tzs.api.entity.DispatchTask;
import com.yeejoin.amos.boot.module.tzs.api.entity.MaintenanceUnit;
import com.yeejoin.amos.boot.module.tzs.api.entity.RescueProcess;
import com.yeejoin.amos.boot.module.tzs.api.entity.RescueStation;
import com.yeejoin.amos.boot.module.tzs.api.entity.UseUnit;
import com.yeejoin.amos.boot.module.tzs.api.enums.DispatchPaperEnums;
import com.yeejoin.amos.boot.module.tzs.api.mapper.RescueProcessMapper;
import com.yeejoin.amos.boot.module.tzs.api.service.IRescueProcessService;
import com.yeejoin.amos.boot.module.tzs.biz.utils.BeanDtoVoUtils;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * 救援过程表服务实现类
 *
 * @author system_generator
 * @date 2021-08-03
 */
@Service
public class RescueProcessServiceImpl extends BaseService<RescueProcessDto,RescueProcess,RescueProcessMapper> implements IRescueProcessService {

    @Autowired
    DispatchPaperServiceImpl dispatchPaperServiceImpl;

    @Autowired
    private DataDictionaryServiceImpl iDataDictionaryService;

    @Autowired
    DispatchTaskServiceImpl dispatchTaskServiceImpl;

    @Autowired
    private AlertFormValueServiceImpl iAlertFormValueService;

    @Autowired
    RepairConsultServiceImpl repairConsultServiceImpl;

    @Autowired
    AlertCalledServiceImpl iAlertCalledService;

    /**
     * 分页查询
     */
    public Page<RescueProcessDto> queryForRescueProcessPage(Page<RescueProcessDto> page)   {
        return this.queryForPage(page, null, false);
    }

    /**
     * 列表查询 示例
     */
    public List<RescueProcessDto> queryForRescueProcessList()   {
        return this.queryForList("" , false);
    }

    @Override
    public RescueProcessDto getProcessByAlertId(Long alertId) {
        // 先通过id 查找过程表
        RescueProcessDto rescueProcessDto = new RescueProcessDto();
        QueryWrapper<RescueProcess> templateQueryWrapper = new QueryWrapper<>();
        templateQueryWrapper.eq("alert_id",alertId);
        RescueProcess rescueProcess = this.getOne(templateQueryWrapper);
        if(rescueProcess == null) {
            rescueProcess = new RescueProcess();
            rescueProcess.setAlertId(alertId);
            this.save(rescueProcess);
        }
        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(); // 相差毫秒数
                SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");//这里想要只保留分秒可以写成"mm:ss"
                formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));
                String hms = formatter.format(arriveTimes);
                rescueProcessDto.setIsTimeout(arriveTimes < 1800000 ? false : true);
                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;
    }

    @Transactional
    @Override
    public Boolean updateByAlertId(RescueProcessDto rescueProcessDto, AgencyUserModel sendUser) {
        QueryWrapper<RescueProcess> templateQueryWrapper = new QueryWrapper<>();
        templateQueryWrapper.eq("alert_id", rescueProcessDto.getAlertId());
        RescueProcess rescueProcess = this.getOne(templateQueryWrapper);
        if (rescueProcess == null)
            throw new BadRequest("救援过程信息未找到");
        if (rescueProcessDto.getDispatchByUser()) { // 手动更新了派遣信息为三级派遣
            // 判断是否存在派遣单 不存在先创建派遣单
            DispatchPaperFormDto dispatchPaperDto = dispatchPaperServiceImpl.selectDispatchPaperDtoByAlertId(rescueProcessDto.getAlertId());
            if (dispatchPaperDto == null || dispatchPaperDto.getDispatchPaper() == null) {
                QueryWrapper<DataDictionary> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("type", "JQLX").eq("name", "困人救援");
                DataDictionary alertCode = iDataDictionaryService.getOne(queryWrapper);
                dispatchPaperDto = dispatchPaperServiceImpl.createDispatchPaper(rescueProcessDto.getAlertId(), alertCode.getCode(), sendUser);
            }

            DispatchPaper dispatchPaper = dispatchPaperDto.getDispatchPaper();
            List<AlertFormValue> dynamicFormAlert = dispatchPaperDto.getDynamicFormAlert();
            // 创建派遣单
            DispatchTaskDto dispatchTaskDto = new DispatchTaskDto();
            dispatchTaskDto.setDispatchTime(rescueProcessDto.getDispatchTime());
            dispatchTaskDto.setOrgTypeCode(DispatchPaperEnums.getEnumByCode("levelThreeUnit").getId());
            dispatchTaskDto.setOrgType(DispatchPaperEnums.getEnumByCode("levelThreeUnit").getValue());
            dispatchTaskDto.setAlertId(rescueProcessDto.getAlertId());
            dispatchTaskDto.setResponseOrgName("119");
            dispatchTaskDto.setResponseUserName("119");
            DispatchTask dispatchTask = BeanDtoVoUtils.convert(dispatchTaskDto, DispatchTask.class);
            dispatchTask.setPaperId(dispatchPaper.getSequenceNbr());
            Boolean flag = dispatchTaskServiceImpl.save(dispatchTask);
            if (flag) { // 创建好派遣任务单以后根据任务单类型修改派遣单信息
                if (dispatchPaper.getRepairOrgId() != null) { // 已经派遣过调派
                    throw new BadRequest("已经派遣过其他力量调派");
                } else {
                    dispatchPaper.setRepairOrgId(-1l);
                    dispatchPaper.setRepairOrgCreditCode("119");
                    dispatchPaper.setRepairOrgTaskId(dispatchTask.getSequenceNbr());
                    // 修改动态字段
                    dynamicFormAlert.stream().forEach(alertFormValue -> {
                        if (alertFormValue.getFieldCode().equals("dispatch_status")) {
                            alertFormValue.setFieldValue("已派遣");
                            alertFormValue.setFieldValueCode("hasDispatched");
                        } else if (alertFormValue.getFieldCode().equals("response_level")) {
                            alertFormValue.setFieldValue("三级响应");
                            alertFormValue.setFieldValueCode("levelThreeUnit");
                        }
                    });
                }
                //  更新派遣单
                dispatchPaperServiceImpl.updateById(dispatchPaper);
                // 保存动态表单数据
                iAlertFormValueService.updateBatchById(dynamicFormAlert);
                // 记录日志
                repairConsultServiceImpl.saveRepairConsultByAlertIdType(dispatchTask.getAlertId(),"PQ", dispatchTask.getSequenceNbr(),sendUser);
            }
        } else {
            rescueProcessDto.setDispatchTime(null);
            rescueProcessDto.setDispatchStatus(null);
            rescueProcessDto.setDispatchUserId(null);
            rescueProcessDto.setDispatchUserName(null);
        }
        boolean arriveByUser = rescueProcessDto.getArriveByUser();
        boolean saveByUser = rescueProcessDto.getSaveByUser();
        if(!arriveByUser) { // 非手动反馈不更新
            rescueProcessDto.setArriveTime(null);
            rescueProcessDto.setArriveFeedbackCode(null);
            rescueProcessDto.setArriveFeedbackType(null);
            rescueProcessDto.setArriveStatus(null);
            rescueProcessDto.setArriveUserId(null);
            rescueProcessDto.setArriveUserName(null);
        }
        if(!saveByUser) {
            rescueProcessDto.setRescueTime(null);
            rescueProcessDto.setRescueFeedbackCode(null);
            rescueProcessDto.setRescueFeedbackType(null);
            rescueProcessDto.setRescueStatus(null);
            rescueProcessDto.setRescueUserId(null);
            rescueProcessDto.setRescueUserName(null);
        }
        rescueProcessDto.setSequenceNbr(rescueProcess.getSequenceNbr());
        rescueProcessDto.setRecDate(rescueProcess.getRecDate());
        rescueProcessDto.setRecUserId(rescueProcess.getRecUserId());
        rescueProcessDto.setRecUserName(rescueProcess.getRecUserName());
        rescueProcess = BeanDtoVoUtils.convert(rescueProcessDto, RescueProcess.class);
        Boolean flag =this.updateById(rescueProcess);
        if(arriveByUser) { // 手动到达
            DispatchPaperFormDto dispatchPaperDto = dispatchPaperServiceImpl.selectDispatchPaperDtoByAlertId(rescueProcessDto.getAlertId());
            if (dispatchPaperDto == null || dispatchPaperDto.getDispatchPaper() == null) {
                throw new BadRequest("派遣单信息未找到");
            }
            // 如果存在三级响应id 则默认三级响应 否则为使用单位
            Long taskId = dispatchPaperDto.getDispatchPaper().getRepairOrgTaskId();
            if(taskId == null) {
                taskId =  dispatchPaperDto.getDispatchPaper().getUseOrgTaskId();
            }
            if(taskId == null) {
                throw new BadRequest("派遣任务单信息未找到");
            }
            repairConsultServiceImpl.saveRepairConsultByAlertIdType( rescueProcessDto.getAlertId(),"DD",taskId,sendUser); //保存接警日志
            // 修改警情到抵达
            iAlertCalledService.updateAlertStageByAlertId(rescueProcessDto.getAlertId(),"DD");
        }
        if(saveByUser) { // 手动救援
            DispatchPaperFormDto dispatchPaperDto = dispatchPaperServiceImpl.selectDispatchPaperDtoByAlertId(rescueProcessDto.getAlertId());
            if (dispatchPaperDto == null || dispatchPaperDto.getDispatchPaper() == null) {
                throw new BadRequest("派遣单信息未找到");
            }
            // 如果存在三级响应id 则默认三级响应 否则为使用单位
            Long taskId = dispatchPaperDto.getDispatchPaper().getRepairOrgTaskId();
            if(taskId == null) {
                taskId =  dispatchPaperDto.getDispatchPaper().getUseOrgTaskId();
            }
            if(taskId == null) {
                throw new BadRequest("派遣任务单信息未找到");
            }
            repairConsultServiceImpl.saveRepairConsultByAlertIdType(rescueProcessDto.getAlertId(),"JC",taskId,sendUser); //保存接警日志
            // 修改警情到抵达
            iAlertCalledService.updateAlertStageByAlertId(rescueProcessDto.getAlertId(),"JC");
        }

        return flag;
    }

    @Override
    public Boolean updateByAlertId(RescueProcessDto rescueProcessDto) {
        QueryWrapper<RescueProcess> templateQueryWrapper = new QueryWrapper<>();
        templateQueryWrapper.eq("alert_id", rescueProcessDto.getAlertId());
        RescueProcess rescueProcess = this.getOne(templateQueryWrapper);
        if (rescueProcess == null)
            throw new BadRequest("救援过程信息未找到");
        rescueProcess = BeanDtoVoUtils.convert(rescueProcessDto, RescueProcess.class);
        Boolean flag =this.updateById(rescueProcess);
        return flag;
    }
}