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

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Maps;
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.tzs.api.dto.AlertCalledDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.AlertCalledFormDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.AlertCalledObjsDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.FormValue;
import com.yeejoin.amos.boot.module.tzs.api.entity.AlertCalled;
import com.yeejoin.amos.boot.module.tzs.api.entity.AlertFormValue;
import com.yeejoin.amos.boot.module.tzs.api.entity.Elevator;
import com.yeejoin.amos.boot.module.tzs.api.entity.RepairConsult;
import com.yeejoin.amos.boot.module.tzs.api.entity.Template;
import com.yeejoin.amos.boot.module.tzs.api.enums.AlertStageEnums;
import com.yeejoin.amos.boot.module.tzs.api.mapper.AlertCalledMapper;
import com.yeejoin.amos.boot.module.tzs.api.service.IAlertCalledService;
import com.yeejoin.amos.boot.module.tzs.api.vo.AlertCalledVo;
import com.yeejoin.amos.boot.module.tzs.biz.utils.AlertBeanDtoVoUtils;
import com.yeejoin.amos.boot.module.tzs.biz.utils.BeanDtoVoUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 警情接警填报记录服务实现类
 *
 * @author litw
 * @date 2021-08-03
 */
@Service
public class AlertCalledServiceImpl extends BaseService<AlertCalledDto,AlertCalled,AlertCalledMapper> implements IAlertCalledService {

    @Autowired
    RedisUtils redisUtils;

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

    @Autowired
    private AlertFormValueServiceImpl iAlertFormValueService;

    @Autowired
    TemplateServiceImpl templateService;

    @Autowired
    private ESAlertCalledService eSAlertCalledService;

    @Autowired
    private ElevatorServiceImpl iElevatorService;

    @Autowired
    private RepairConsultServiceImpl repairConsultService;

    @Autowired
    AlertCalledMapper alertCalledMapper;

    @Autowired
    RescueProcessServiceImpl rescueProcessServiceImpl;


    private final Logger logger = LogManager.getLogger(AlertCalledServiceImpl.class);


    @Override
    public Object selectAlertCalledById(Long id) {
        if(redisUtils.hasKey(RedisKey.TZS_ALERTCALLED_ID+id)){
            Object obj= redisUtils.get(RedisKey.TZS_ALERTCALLED_ID+id);
            return obj;
        }else{
            // 警情基本信息
            AlertCalled alertCalled = this.getById(id);
            QueryWrapper<AlertFormValue> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("alert_called_id", id);
            // 警情动态表单数据
            List<AlertFormValue> list = iAlertFormValueService.list(queryWrapper);
            List<FormValue> formValue = new ArrayList<FormValue>();
            if(list!=null&&list.size()>0) {
                for (AlertFormValue alertFormValue : list) {
                    FormValue value = new FormValue(alertFormValue.getFieldCode(), alertFormValue.getFieldName(), "text", alertFormValue.getFieldValue(),alertFormValue.getBlock());
                    formValue.add(value);
                }
            }
            AlertCalledDto alertCalledDto = BeanDtoVoUtils.convert(alertCalled,AlertCalledDto.class);
            AlertCalledVo alertCalledVo = AlertBeanDtoVoUtils.convertAlertCalledDtoToVo(alertCalledDto);
            QueryWrapper<Elevator> elevatorQueryWrapper = new QueryWrapper<>();
            elevatorQueryWrapper.eq("rescue_code", alertCalled.getDeviceId());
            elevatorQueryWrapper.eq("register_code", alertCalled.getRegistrationCode());
            Elevator elevator =  iElevatorService.getOne(elevatorQueryWrapper);
            if(null !=  elevator) {
                alertCalledVo.setAddress(elevator.getAddress());
                alertCalledVo.setProvince(elevator.getProvince());
                alertCalledVo.setCity(elevator.getCity());
                alertCalledVo.setDistrict(elevator.getDistrict());
                alertCalledVo.setUseStatus(elevator.getUseStatus());
                alertCalledVo.setUseSiteCategory(elevator.getUseSiteCategory());
                alertCalledVo.setUseUnit(elevator.getUseUnit());
                alertCalledVo.setRegionCode(elevator.getRegionCode());
            }
            AlertCalledFormDto alertCalledFormVo = new AlertCalledFormDto(alertCalledVo, formValue);

            redisUtils.set(RedisKey.TZS_ALERTCALLED_ID+id, JSON.toJSON(alertCalledFormVo),time);
            return alertCalledFormVo;
        }
    }

    @Override
    public AlertCalledFormDto selectAlertCalledByIdNoCache(Long id) {
        // 警情基本信息
        AlertCalled alertCalled = this.getById(id);
        QueryWrapper<AlertFormValue> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("alert_called_id", id);
        // 警情动态表单数据
        List<AlertFormValue> list = iAlertFormValueService.list(queryWrapper);
        List<FormValue> formValue = new ArrayList<FormValue>();
        if(list!=null&&list.size()>0) {
            for (AlertFormValue alertFormValue : list) {
                FormValue value = new FormValue(alertFormValue.getFieldCode(), alertFormValue.getFieldName(), "text", alertFormValue.getFieldValue(),alertFormValue.getBlock());
                formValue.add(value);
            }
        }
        AlertCalledDto alertCalledDto = BeanDtoVoUtils.convert(alertCalled,AlertCalledDto.class);
        AlertCalledVo alertCalledVo = AlertBeanDtoVoUtils.convertAlertCalledDtoToVo(alertCalledDto);
        QueryWrapper<Elevator> elevatorQueryWrapper = new QueryWrapper<>();
        elevatorQueryWrapper.eq("rescue_code", alertCalled.getDeviceId());
        elevatorQueryWrapper.eq("register_code", alertCalled.getRegistrationCode());
        Elevator elevator =  iElevatorService.getOne(elevatorQueryWrapper);
        if(null !=  elevator) {
            alertCalledVo.setAddress(elevator.getAddress());
            alertCalledVo.setProvince(elevator.getProvince());
            alertCalledVo.setCity(elevator.getCity());
            alertCalledVo.setDistrict(elevator.getDistrict());
            alertCalledVo.setUseStatus(elevator.getUseStatus());
            alertCalledVo.setUseSiteCategory(elevator.getUseSiteCategory());
            alertCalledVo.setUseUnit(elevator.getUseUnit());
            alertCalledVo.setRegionCode(elevator.getRegionCode());
        }
        AlertCalledFormDto alertCalledFormVo = new AlertCalledFormDto(alertCalledVo, formValue);
        return alertCalledFormVo;
    }


    /**
     *
     * <pre>
     * 保存警情信息
     * </pre>
     *
     * @param alertCalledObjsDto
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public AlertCalledObjsDto createAlertCalled(AlertCalledObjsDto alertCalledObjsDto) {
        try {
            // 警情基本信息

            AlertCalled alertCalled = BeanDtoVoUtils.convert(alertCalledObjsDto.getAlertCalledDto(),AlertCalled.class);

            alertCalled.setCallTime(DateUtils.longStr2Date(alertCalled.getCallTimeStr()));

            // 判断是否归并警情
            if (alertCalled.getFatherAlert() != null) {
                // 警情归并，设置当前警情状态为结束。
                alertCalled.setAlertStatus(true);
                alertCalled.setAlertStage(AlertStageEnums.JJ.getValue());
                alertCalled.setAlertStageCode(AlertStageEnums.JJ.getCode());
                alertCalled.setType(AlertStageEnums.JQGB.getValue());
                alertCalled.setTypeCode(AlertStageEnums.JQGB.getCode());
                this.save(alertCalled);
                // 动态表单
                List<AlertFormValue> alertFormValuelist = alertCalledObjsDto.getAlertFormValue();
                // 填充警情主键
                alertFormValuelist.stream().forEach(alertFormValue -> {
                    alertFormValue.setAlertCalledId(alertCalled.getSequenceNbr());
                    alertFormValue.setAlertTypeCode(alertCalled.getAlarmTypeCode());
                });
                // 保存动态表单数据
                iAlertFormValueService.saveBatch(alertFormValuelist);
                // 警情基本信息
                AlertCalled alertCalledFather = this.getById(alertCalled.getFatherAlert());
                alertCalledObjsDto.setAlertCalledDto(BeanDtoVoUtils.convert(alertCalledFather,AlertCalledDto.class));

            } else {
                // 警情报送
                // ****************************************************待确认开发
                alertCalled.setAlertStatus(false);
                alertCalled.setIsDelete(false);
                alertCalled.setAlertStage(AlertStageEnums.JJ.getValue());
                alertCalled.setAlertStageCode(AlertStageEnums.JJ.getCode());
                alertCalled.setType(AlertStageEnums.JQCB.getValue());
                alertCalled.setTypeCode(AlertStageEnums.JQCB.getCode());
                this.save(alertCalled);

                // 动态表单
                List<AlertFormValue> alertFormValuelist = alertCalledObjsDto.getAlertFormValue();
                // 填充警情主键
                alertFormValuelist.stream().forEach(alertFormValue -> {
                    alertFormValue.setAlertCalledId(alertCalled.getSequenceNbr());
                    alertFormValue.setAlertTypeCode(alertCalled.getAlarmTypeCode());
                });
                if(AlertStageEnums.KRJY.getCode().equals(alertCalled.getAlarmTypeCode()) ) {
                    //困人救援创建警情时创建救援过程信息
                    rescueProcessServiceImpl.getProcessByAlertId(alertCalled.getSequenceNbr());
                }

                // 保存动态表单数据
                iAlertFormValueService.saveBatch(alertFormValuelist);
                alertCalledObjsDto.setAlertCalledDto(BeanDtoVoUtils.convert(alertCalled,AlertCalledDto.class));
                alertCalledObjsDto.setAlertFormValue(alertFormValuelist);

                //保存处置记录-接警
                if(AlertStageEnums.KRJY.getCode().equals(alertCalled.getAlarmTypeCode())) {
                    saveRapairConsylt(AlertStageEnums.JJ.getCode(),alertCalled);
                } else if(AlertStageEnums.GZWX.getCode().equals(alertCalled.getAlarmTypeCode())) {
                    saveRapairConsylt(AlertStageEnums.JJ.getCode(),alertCalled);
                } else {
                    saveRapairConsylt(AlertStageEnums.JJ.getCode(),alertCalled);
                }
            }

            /**
             * 同步保存ES
             */
            eSAlertCalledService.saveAlertCalledToES(alertCalled);

            return alertCalledObjsDto;
        } catch (Exception e) {
            logger.error("报送失败",e);
            throw new RuntimeException("报送失败，系统异常!");
        }
    }

    private void saveRapairConsylt(String typeCode,AlertCalled alertCalled ) throws ParseException {
        // 获取警情接警处置记录模板
        Template template = templateService.getOne(new QueryWrapper<Template>().eq("type_code",
                typeCode).eq("format", false));
        String templateContent = template.getContent();
        String transferDetails = templateContent.replace("callTime", DateUtils.dateTimeToDateString(alertCalled.getCallTime()))
                .replace("user",alertCalled.getRecUserName()).replace("emergencyCall",alertCalled.getEmergencyCall());

        RepairConsult repairConsult = new RepairConsult();
        repairConsult.setParentId(alertCalled.getSequenceNbr());
        repairConsult.setType(alertCalled.getAlarmTypeCode());
        repairConsult.setAlertStageCode(alertCalled.getAlertStageCode());
        repairConsult.setAlertStatus(alertCalled.getAlertStage());
        repairConsult.setContactUser(alertCalled.getEmergencyPerson());
        repairConsult.setContactPhone(alertCalled.getContactPhone());
        repairConsult.setDescription(transferDetails);
        repairConsultService.save(repairConsult);
    }

    public Map<String, Object> getAlertInfoList(String beginDate, String endDate,String orgCode, String recUserId) {

        Map<String, Object> result = Maps.newHashMap();
        Map<String, Integer> statusCountMap = alertCalledMapper.queryAlertStatusCount(beginDate, endDate,orgCode,recUserId);

        result.put("calledCount",statusCountMap.get("calledCount"));
        result.put("majorAlertCount",statusCountMap.get("majorAlertCount"));
        result.put("sleepyIncidentCount",statusCountMap.get("sleepyIncidentCount"));
        result.put("faultRescueCount",statusCountMap.get("faultRescueCount"));
        result.put("suggestionsCount",statusCountMap.get("suggestionsCount"));

        return result;
    }

}