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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.AlertCalledQueryDto;
import com.yeejoin.amos.boot.module.tzs.api.dto.ESAlertCalledDto;
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.ESAlertCalled;
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.enums.AlertStatusEnum;
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.biz.utils.AlertBeanDtoVoUtils;
import com.yeejoin.amos.boot.module.tzs.biz.utils.BeanDtoVoUtils;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.LinkedList;
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
    AlertCalledMapper alertCalledMapper;

    @Autowired
    RescueProcessServiceImpl rescueProcessServiceImpl;

    @Autowired
    RepairConsultServiceImpl repairConsultServiceImpl;

    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);
            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) {
                alertCalledDto.setAddress(elevator.getAddress());
                alertCalledDto.setProvince(elevator.getProvince());
                alertCalledDto.setCity(elevator.getCity());
                alertCalledDto.setDistrict(elevator.getDistrict());
                alertCalledDto.setUseStatus(elevator.getUseStatus());
                alertCalledDto.setUseSiteCategory(elevator.getUseSiteCategory());
                alertCalledDto.setUseUnit(elevator.getUseUnit());
                alertCalledDto.setRegionCode(elevator.getRegionCode());
            }
            AlertCalledFormDto alertCalledFormVo = new AlertCalledFormDto(alertCalledDto, 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);
        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) {
            alertCalledDto.setAddress(elevator.getAddress());
            alertCalledDto.setProvince(elevator.getProvince());
            alertCalledDto.setCity(elevator.getCity());
            alertCalledDto.setDistrict(elevator.getDistrict());
            alertCalledDto.setUseStatus(elevator.getUseStatus());
            alertCalledDto.setUseSiteCategory(elevator.getUseSiteCategory());
            alertCalledDto.setUseUnit(elevator.getUseUnit());
            alertCalledDto.setRegionCode(elevator.getRegionCode());
        }
        AlertCalledFormDto alertCalledFormVo = new AlertCalledFormDto(alertCalledDto, formValue);
        return alertCalledFormVo;
    }

    @Override
    public List<AlertCalledQueryDto> queryAlertListByQueryDto(AlertCalledQueryDto alertCalledQueryDto) {
        List<AlertCalledQueryDto> list = alertCalledMapper.queryAlertListByQueryDto(alertCalledQueryDto);
        return list;
    }

    @Override
    public Boolean updateAlertStageByAlertId(Long alertId, String alertStage) {
        UpdateWrapper<AlertCalled> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("sequence_nbr",alertId);
        AlertStageEnums stage = AlertStageEnums.getEnumByCode(alertStage);
        updateWrapper.set("alert_stage_code",stage.getId());
        updateWrapper.set("alert_stage",stage.getValue());
        return this.update(updateWrapper);
    }


    /**
     *
     * <pre>
     * 保存警情信息
     * </pre>
     *
     * @param alertCalledObjsDto
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public AlertCalledObjsDto createAlertCalled(AlertCalledObjsDto alertCalledObjsDto, AgencyUserModel user) {
        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.getId());
                alertCalled.setType(AlertStageEnums.JQGB.getValue());
                alertCalled.setTypeCode(AlertStageEnums.JQGB.getId());
                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.getId());
                alertCalled.setType(AlertStageEnums.JQCB.getValue());
                alertCalled.setTypeCode(AlertStageEnums.JQCB.getId());
                this.save(alertCalled);

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

                // 保存动态表单数据
                iAlertFormValueService.saveBatch(alertFormValuelist);
                alertCalledObjsDto.setAlertCalledDto(BeanDtoVoUtils.convert(alertCalled,AlertCalledDto.class));
                alertCalledObjsDto.setAlertFormValue(alertFormValuelist);
                //保存处置记录-接警
                repairConsultServiceImpl.saveRepairConsultByAlertIdType(alertCalled.getSequenceNbr(),"JJ",null, user); //保存接警日志
            }

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

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

    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;
    }

}