package com.yeejoin.amos.patrol.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.patrol.business.bo.CheckInputSyncBo;
import com.yeejoin.amos.patrol.business.bo.PlanTaskSyncBo;
import com.yeejoin.amos.patrol.business.dao.mapper.CheckMapper;
import com.yeejoin.amos.patrol.business.dao.mapper.PlanTaskMapper;
import com.yeejoin.amos.patrol.business.dao.repository.IPlanTaskDao;
import com.yeejoin.amos.patrol.business.dao.repository.IPlanTaskDetailDao;
import com.yeejoin.amos.patrol.business.service.intfc.IPatrolDataSyncService;
import com.yeejoin.amos.patrol.common.enums.PatrolDataSyncTopicEnum;
import com.yeejoin.amos.patrol.common.enums.PlanTaskTypeStatusEnum;
import com.yeejoin.amos.patrol.dao.entity.*;
import com.yeejoin.amos.patrol.mqtt.WebMqttComponent;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Async
@Slf4j
public class PatrolDataSyncServiceImpl implements IPatrolDataSyncService {

    @Autowired
    private WebMqttComponent webMqttComponent;

    @Autowired
    private IPlanTaskDao planTaskDao;

    @Autowired
    private IPlanTaskDetailDao planTaskDetailDao;

    @Value("${emq.patrol.sync.switch}")
    private Boolean patrolSyncSwitch;

    @Autowired
    private CheckMapper checkMapper;


    private String P_STATIC_DAY = "p_static_day";

    private String P_STATIC_MONTH = "p_static_month";

    private String P_STATIC_WEEK = "p_static_week";

    @Autowired
    private PlanTaskMapper planTaskMapper;

    @Override
    public void checkDataSync(Check check) {
        if (check != null) {
            try {
                String message = buildSyncMessage(PatrolDataSyncTopicEnum.CHECK.getTopic(), check);
                webMqttComponent.publish(PatrolDataSyncTopicEnum.EQM_PATROL_CREATED.getTopic(), message);
                if (patrolSyncSwitch) {
                    webMqttComponent.publish(PatrolDataSyncTopicEnum.CHECK.getTopic(), JSON.toJSONString(check, SerializerFeature.WriteMapNullValue));
                }
                String isOk = check.getIsOk();
                long taskId = check.getPlanTaskId();
                long taskDetailId = check.getPlanTaskDetailId();
                Optional<PlanTask> planTaskOptional = planTaskDao.findById(taskId);
                planTaskOptional.ifPresent(this::planTaskDataSync);
                List<PlanTaskDetail> planTaskDetailList = planTaskDetailDao.findAllByIdAndStatus(taskDetailId, isOk);
                if (CollectionUtils.isNotEmpty(planTaskDetailList)) {
                    planTaskDetailList.forEach(x -> {
                        String detailMessage = buildSyncMessage(PatrolDataSyncTopicEnum.PLAN_TASK_DETAIL.getTopic(), x);
                        webMqttComponent.publish(PatrolDataSyncTopicEnum.EQM_PATROL_CREATED.getTopic(), detailMessage);
                        if (patrolSyncSwitch) {
                            webMqttComponent.publish(PatrolDataSyncTopicEnum.PLAN_TASK_DETAIL.getTopic(), JSON.toJSONString(x, SerializerFeature.WriteMapNullValue));
                        }
                    });
                }
            } catch (Exception e) {
                log.error("站端与中心级巡检数据【check或planTaskDetail】同步推送失败-----------" + e.getMessage());
            }
        }
    }

    @Override
    public void checkDataSync(List<Check> checkList) {
        if (CollectionUtils.isNotEmpty(checkList)) {
            try {
                checkList.forEach(check -> {
                    String message = buildSyncMessage(PatrolDataSyncTopicEnum.CHECK.getTopic(), check);
                    webMqttComponent.publish(PatrolDataSyncTopicEnum.EQM_PATROL_CREATED.getTopic(), message);
                    if (patrolSyncSwitch) {
                        webMqttComponent.publish(PatrolDataSyncTopicEnum.CHECK.getTopic(), JSON.toJSONString(check, SerializerFeature.WriteMapNullValue));
                    }
                    String isOk = check.getIsOk();
                    long taskId = check.getPlanTaskId();
                    long taskDetailId = check.getPlanTaskDetailId();
                    Optional<PlanTask> planTaskOptional = planTaskDao.findById(taskId);
                    planTaskOptional.ifPresent(this::planTaskDataSync);
                    List<PlanTaskDetail> planTaskDetailList = planTaskDetailDao.findAllByIdAndStatus(taskDetailId, isOk);
                    if (CollectionUtils.isNotEmpty(planTaskDetailList)) {
                        planTaskDetailList.forEach(x -> {
                            String detailMessage = buildSyncMessage(PatrolDataSyncTopicEnum.PLAN_TASK_DETAIL.getTopic(), x);
                            webMqttComponent.publish(PatrolDataSyncTopicEnum.EQM_PATROL_CREATED.getTopic(), detailMessage);
                            if (patrolSyncSwitch) {
                                webMqttComponent.publish(PatrolDataSyncTopicEnum.PLAN_TASK_DETAIL.getTopic(), JSON.toJSONString(x, SerializerFeature.WriteMapNullValue));
                            }
                        });
                    }
                });
            } catch (Exception e) {
                log.error("站端与中心级巡检数据【check或planTaskDetail】同步推送失败-----------" + e.getMessage());
            }
        }
    }

    @Override
    public void checkInputDataSync(CheckInput checkInput) {
        try {
            if (checkInput != null) {
                String message = buildSyncMessage(PatrolDataSyncTopicEnum.CHECK_INPUT.getTopic(), checkInput);
                webMqttComponent.publish(PatrolDataSyncTopicEnum.EQM_PATROL_CREATED.getTopic(), message);
                if (patrolSyncSwitch) {
                    webMqttComponent.publish(PatrolDataSyncTopicEnum.CHECK_INPUT.getTopic(), JSON.toJSONString(checkInput, SerializerFeature.WriteMapNullValue));
                }
            }
        } catch (Exception e) {
            log.error("站端与中心级巡检数据【checkInput】同步推送失败-----------" + e.getMessage());
        }
    }

    @Override
    public void checkInputDataSync(List<CheckInput> checkInputList) {
        try {
            if (CollectionUtils.isNotEmpty(checkInputList)) {
                checkInputList.forEach(x -> {
                    String message = buildSyncMessage(PatrolDataSyncTopicEnum.CHECK_INPUT.getTopic(), x);
                    webMqttComponent.publish(PatrolDataSyncTopicEnum.EQM_PATROL_CREATED.getTopic(), message);
                    if (patrolSyncSwitch) {
                        webMqttComponent.publish(PatrolDataSyncTopicEnum.CHECK_INPUT.getTopic(), JSON.toJSONString(x, SerializerFeature.WriteMapNullValue));
                    }
                });
            }
        } catch (Exception e) {
            log.error("站端与中心级巡检数据【checkInput】同步推送失败-----------" + e.getMessage());
        }
    }

    @Override
    public void checkShotDataSync(List<CheckShot> checkShotList) {
        try {
            if (CollectionUtils.isNotEmpty(checkShotList)) {
                checkShotList.forEach(x -> {
                    String message = buildSyncMessage(PatrolDataSyncTopicEnum.CHECK_SHOT.getTopic(), x);
                    webMqttComponent.publish(PatrolDataSyncTopicEnum.EQM_PATROL_CREATED.getTopic(), message);
                    if (patrolSyncSwitch) {
                        webMqttComponent.publish(PatrolDataSyncTopicEnum.CHECK_SHOT.getTopic(), JSON.toJSONString(x, SerializerFeature.WriteMapNullValue));
                    }
                });
            }
        } catch (Exception e) {
            log.error("站端与中心级巡检数据【checkShot】同步推送失败-----------" + e.getMessage());
        }
    }

    @Override
    public void checkInputBoDataSync(CheckInputSyncBo checkInputSyncBo) {
        try {
            if (checkInputSyncBo != null) {
                String message = buildSyncMessage(PatrolDataSyncTopicEnum.CHECK_INPUT_BO.getTopic(), checkInputSyncBo);
                webMqttComponent.publish(PatrolDataSyncTopicEnum.EQM_PATROL_CREATED.getTopic(), message);
                webMqttComponent.publish(PatrolDataSyncTopicEnum.PATROL_CHECK_INPUT_TO_DATASYS.getTopic(), JSON.toJSONString(checkInputSyncBo, SerializerFeature.WriteMapNullValue));
                if (patrolSyncSwitch) {
                    webMqttComponent.publish(PatrolDataSyncTopicEnum.CHECK_INPUT_BO.getTopic(), JSON.toJSONString(checkInputSyncBo, SerializerFeature.WriteMapNullValue));
                }
            }
        } catch (Exception e) {
            log.error("站端与中心级巡检数据【CheckInputSyncBo】同步推送失败-----------" + e.getMessage());
        }
    }

    @Override
    public void checkInputBoDataSync(List<CheckInputSyncBo> checkInputSyncBoList) {
        try {
            if (CollectionUtils.isNotEmpty(checkInputSyncBoList)) {
                checkInputSyncBoList.forEach(x -> {
                    String message = buildSyncMessage(PatrolDataSyncTopicEnum.CHECK_INPUT_BO.getTopic(), x);
                    webMqttComponent.publish(PatrolDataSyncTopicEnum.EQM_PATROL_CREATED.getTopic(), message);
                    webMqttComponent.publish(PatrolDataSyncTopicEnum.PATROL_CHECK_INPUT_TO_DATASYS.getTopic(), JSON.toJSONString(x, SerializerFeature.WriteMapNullValue));
                    if (patrolSyncSwitch) {
                        webMqttComponent.publish(PatrolDataSyncTopicEnum.CHECK_INPUT_BO.getTopic(), JSON.toJSONString(x, SerializerFeature.WriteMapNullValue));
                    }
                });
            }
        } catch (Exception e) {
            log.error("站端与中心级巡检数据【CheckInputSyncBo】同步推送失败-----------" + e.getMessage());
        }
    }

    @Override
    public void planTaskDataSync(PlanTask planTask) {
        try {
            if (planTask != null) {
                PlanTaskSyncBo planTaskSyncBo = buildPlanTaskBo(planTask);
                String message = buildSyncMessage(PatrolDataSyncTopicEnum.PLAN_TASK.getTopic(), planTaskSyncBo);
                webMqttComponent.publish(PatrolDataSyncTopicEnum.EQM_PATROL_CREATED.getTopic(), message);
                if (patrolSyncSwitch) {
                    webMqttComponent.publish(PatrolDataSyncTopicEnum.PLAN_TASK.getTopic(), JSON.toJSONString(planTaskSyncBo, SerializerFeature.WriteMapNullValue));
                }
            }
        } catch (Exception e) {
            log.error("站端与中心级巡检数据【planTask】同步推送失败-----------" + e.getMessage());
        }
    }

    @Override
    public void planTaskDataSync(List<PlanTask> planTaskList) {
        try {
            if (CollectionUtils.isNotEmpty(planTaskList)) {
                planTaskList.forEach(x -> {
                    PlanTaskSyncBo planTaskSyncBo = buildPlanTaskBo(x);
                    String message = buildSyncMessage(PatrolDataSyncTopicEnum.PLAN_TASK.getTopic(), planTaskSyncBo);
                    webMqttComponent.publish(PatrolDataSyncTopicEnum.EQM_PATROL_CREATED.getTopic(), message);
                    if (patrolSyncSwitch) {
                        webMqttComponent.publish(PatrolDataSyncTopicEnum.PLAN_TASK.getTopic(), JSON.toJSONString(planTaskSyncBo, SerializerFeature.WriteMapNullValue));
                    }
                });
            }
        } catch (Exception e) {
            log.error("站端与中心级巡检数据【PlanTask】同步推送失败-----------" + e.getMessage());
        }
    }



    @Override
    public void planTaskDetailDataSync(List<PlanTaskDetail> planTaskDetailList) {
        try {
            if (CollectionUtils.isNotEmpty(planTaskDetailList)) {
                planTaskDetailList.forEach(x -> {
                    String message = buildSyncMessage(PatrolDataSyncTopicEnum.PLAN_TASK_DETAIL.getTopic(), x);
                    webMqttComponent.publish(PatrolDataSyncTopicEnum.EQM_PATROL_CREATED.getTopic(), message);
                    if (patrolSyncSwitch) {
                        webMqttComponent.publish(PatrolDataSyncTopicEnum.PLAN_TASK_DETAIL.getTopic(), JSON.toJSONString(x, SerializerFeature.WriteMapNullValue));
                    }
                });
            }
        } catch (Exception e) {
            log.error("站端与中心级巡检数据【PlanTaskDetail】同步推送失败-----------" + e.getMessage());
        }
    }

    @Override
    @Async("asyncServiceExecutor")
    public void taskStatic(String runDate) {
        try {
            runDate = DateUtils.dateFormat(new Date(), DateUtils.DATE_PATTERN);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        log.info("开始更新统计表========");
        // 插入日统计表
        List<Map<String, Object>> listDay = checkMapper.planCount(runDate, null, String.valueOf(PlanTaskTypeStatusEnum.day.getValue()), null,null,null);
        List<StaticDay> staticDays = listDay.stream().map(e->{
            String s = JSON.toJSONString(e);
            return JSON.parseObject(s, StaticDay.class);
        }).collect(Collectors.toList());
        // 插入周统计表
        List<Map<String, Object>> listWeek = checkMapper.planCount(runDate, null, String.valueOf(PlanTaskTypeStatusEnum.week.getValue()), null,null,null);
        List<StaticDay> staticWeeks = listWeek.stream().map(e->{
            String s = JSON.toJSONString(e);
            return JSON.parseObject(s, StaticDay.class);
        }).collect(Collectors.toList());
        // 插入月统计表
        List<Map<String, Object>> listMonth = checkMapper.planCount(runDate, null, String.valueOf(PlanTaskTypeStatusEnum.month.getValue()), null,null,null);
        List<StaticDay> staticMonths = listMonth.stream().map(e->{
            String s = JSON.toJSONString(e);
            return JSON.parseObject(s, StaticDay.class);
        }).collect(Collectors.toList());

        if(!staticDays.isEmpty()) {
            planTaskMapper.updateData(P_STATIC_DAY, staticDays);
        }
        if(!staticWeeks.isEmpty()) {
            planTaskMapper.updateData(P_STATIC_WEEK, staticWeeks);
        }
        if(!staticMonths.isEmpty()) {
            planTaskMapper.updateData(P_STATIC_MONTH, staticMonths);
        }
        log.info("更新统计表完成=======");
    }

    public String buildSyncMessage(String topic, Object object) {
        Map<String, Object> map = new HashMap<>();
        map.put("topic", topic);
        map.put("data", object);
        return JSON.toJSONString(map, SerializerFeature.WriteMapNullValue);
    }

    public PlanTaskSyncBo buildPlanTaskBo(PlanTask planTask) {
        PlanTaskSyncBo taskSyncBo = new PlanTaskSyncBo();
        BeanUtils.copyProperties(planTask, taskSyncBo);
        return taskSyncBo;
    }
}
