package com.sw.mes.scheduled;

import com.sw.mes.core.utils.DateUtil;
import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.eam.deviceinspect.dto.DeviceInspectPlanDetailRecordDto;
import com.sw.mes.eam.deviceinspect.dto.DeviceInspectPlanNormDetailRecordDto;
import com.sw.mes.eam.deviceinspect.dto.DeviceInspectPlanRecordDto;
import com.sw.mes.eam.deviceinspect.entity.DeviceInspectPlan;
import com.sw.mes.eam.deviceinspect.entity.DeviceInspectPlanDetail;
import com.sw.mes.eam.deviceinspect.entity.DeviceInspectPlanNormDetail;
import com.sw.mes.eam.deviceinspect.service.DeviceInspectPlanDetailService;
import com.sw.mes.eam.deviceinspect.service.DeviceInspectPlanNormDetailService;
import com.sw.mes.eam.deviceinspect.service.DeviceInspectPlanRecordService;
import com.sw.mes.eam.deviceinspect.service.DeviceInspectPlanService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @Author: JS111816
 * @Description:
 * @Date: 2023/1/6
 * @Modified By:
 **/
@Slf4j
@Component
public class DeviceInspectPlanTask {
    @Autowired
    private DeviceInspectPlanService deviceInspectPlanService;

    @Autowired
    private DeviceInspectPlanDetailService deviceInspectPlanDetailService;

    @Autowired
    private DeviceInspectPlanNormDetailService deviceInspectPlanNormDetailService;

    @Autowired
    private DeviceInspectPlanRecordService deviceInspectPlanRecordService;


    @XxlJob("scheduleDeviceInspectPlanTask")
    public void scheduleDeviceInspectPlanTask() {
        //查询所有启用的巡检计划单
        List<DeviceInspectPlan> deviceInspectPlans = deviceInspectPlanService.queryAllInspectPlanByEnable();
        for (int i = 0; i < deviceInspectPlans.size(); i++) {
            DeviceInspectPlan deviceInspectPlan = deviceInspectPlans.get(i);
            Integer planId = deviceInspectPlan.getId();
            //下次巡检时间
            Date nextInspectDate = deviceInspectPlan.getNextInspectDate();
            //上次巡检时间
            Date lastInspectDate = deviceInspectPlan.getLastInspectDate();
            //截止时间
            Date deadline = deviceInspectPlan.getDeadline();
            //当前时间
            Date cureentDate = new Date();
            String cureentYearAndMothAndDay = DateUtil.formatDate(cureentDate, "yyyy-MM-dd");
            //计划周期
            Integer rolling = deviceInspectPlan.getRolling();
            String rollUnit = deviceInspectPlan.getRollUnit();
            try {
                //计算下次要巡检的时间
                Date nextPlanDate = deviceInspectPlanService.getDate(deviceInspectPlan.getLastInspectDate() == null ? nextInspectDate : deviceInspectPlan.getLastInspectDate(), rolling, rollUnit);
                if (validateTask(deviceInspectPlan, nextInspectDate, lastInspectDate, deadline, cureentDate, cureentYearAndMothAndDay)) {
                    continue;
                }
                //更新巡检计划下次执行时间
                deviceInspectPlanService.updateLastInspectDate(planId, nextPlanDate);
                //保存巡检记录
                List<DeviceInspectPlanDetail> deviceInspectPlanDetailList = deviceInspectPlanDetailService.findByPlanId(planId);
                DeviceInspectPlanRecordDto deviceInspectPlanRecordDto = new DeviceInspectPlanRecordDto();
                deviceInspectPlanRecordDto.setPlanId(planId);
                deviceInspectPlanRecordDto.setPlanName(deviceInspectPlan.getName());
                deviceInspectPlanRecordDto.setExecuteRange(deviceInspectPlan.getExecuteRange());
                List<DeviceInspectPlanDetailRecordDto> planDetailRecordDtos = new ArrayList<>();
                deviceInspectPlanDetailList.stream().forEach(t -> {
                    Integer planDetailId = t.getId();
                    List<DeviceInspectPlanNormDetail> byPlanDetailIdList = deviceInspectPlanNormDetailService.findByPlanDetailId(planDetailId);
                    DeviceInspectPlanDetailRecordDto deviceInspectPlanDetailRecordDto = new DeviceInspectPlanDetailRecordDto();
                    //
                    List<DeviceInspectPlanNormDetailRecordDto> normDetailRecordDto = new ArrayList<>();
                    byPlanDetailIdList.stream().forEach(tt -> {
                        DeviceInspectPlanNormDetailRecordDto deviceInspectPlanNormDetailRecordDto = new DeviceInspectPlanNormDetailRecordDto();
                        deviceInspectPlanNormDetailRecordDto.setName(tt.getName());
                        deviceInspectPlanNormDetailRecordDto.setNormal(tt.getNormal());
                        deviceInspectPlanNormDetailRecordDto.setRecordMode(tt.getRecordMode());
                        normDetailRecordDto.add(deviceInspectPlanNormDetailRecordDto);
                    });
                    deviceInspectPlanDetailRecordDto.setNormDetailRecordDto(normDetailRecordDto);
                    deviceInspectPlanDetailRecordDto.setDeviceId(t.getDeviceId());
                    deviceInspectPlanDetailRecordDto.setDeviceCode(t.getDeviceCode());
                    deviceInspectPlanDetailRecordDto.setDeviceName(t.getDeviceName());
                    deviceInspectPlanDetailRecordDto.setNormNames(t.getNormNames());
                    deviceInspectPlanDetailRecordDto.setNormIds(t.getNormIds());
                    planDetailRecordDtos.add(deviceInspectPlanDetailRecordDto);
                });
                deviceInspectPlanRecordDto.setPlanDetailRecordDtos(planDetailRecordDtos);
                deviceInspectPlanRecordService.saveOrUpdateByTask(deviceInspectPlanRecordDto);

            } catch (ParseException e) {
                log.info("计划名称：" + deviceInspectPlan.getName() + "计划编号：" + deviceInspectPlan.getCode() + "出现异常，异常信息" + e.getMessage());
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * @param deviceInspectPlan
     * @param nextInspectDate          下次执行时间
     * @param lastInspectDate          上次执行时间
     * @param cureentDate              当前时间
     * @param cureentYearAndMothAndDay
     * @return
     * @throws ParseException
     */
    private boolean validateTask(DeviceInspectPlan deviceInspectPlan, Date nextInspectDate, Date lastInspectDate, Date deadline, Date cureentDate, String cureentYearAndMothAndDay) throws ParseException {
        //在跳过时间内
        if ((deviceInspectPlan.getPassStartTime1() != null && deviceInspectPlan.getPassEndTime1() != null) && (cureentDate.compareTo(DateUtil.toDate(cureentYearAndMothAndDay + " " + deviceInspectPlan.getPassStartTime1() + ":00", "yyyy-MM-dd HH:mm:ss")) > 0 && cureentDate.compareTo(DateUtil.toDate(cureentYearAndMothAndDay + " " + deviceInspectPlan.getPassEndTime1() + ":00", "yyyy-MM-dd HH:mm:ss")) > 0)) {
            return true;
        }
        if ((deviceInspectPlan.getPassStartTime2() != null && deviceInspectPlan.getPassEndTime2() != null) && (cureentDate.compareTo(DateUtil.toDate(cureentYearAndMothAndDay + " " + deviceInspectPlan.getPassStartTime2() + ":00", "yyyy-MM-dd HH:mm:ss")) > 0 && cureentDate.compareTo(DateUtil.toDate(cureentYearAndMothAndDay + " " + deviceInspectPlan.getPassEndTime2() + ":00", "yyyy-MM-dd HH:mm:ss")) > 0)) {
            return true;
        }
        if (deviceInspectPlan.getPassDate() != null && StringUtils.equals(cureentYearAndMothAndDay, deviceInspectPlan.getPassDate())) {
            return true;
        }
        if (deviceInspectPlan.getIsPassSat() != null && deviceInspectPlan.getIsPassSat() && isPasssWeekend(cureentDate)) {
            return true;
        }

        if (deviceInspectPlan.getIsPassSat() != null && deviceInspectPlan.getIsPassSun() && isPasssWeekend(cureentDate)) {
            return true;
        }

        //如果上次执行时间为空，说明没有执行过,执行。
        if (lastInspectDate == null) {
            //再次判断是不是在下一次执行时间内
            if(cureentDate.compareTo(nextInspectDate) >= 0){
                return false;
            }
            else{
                return true;
            }

        } else  {
            if(cureentDate.compareTo(lastInspectDate) >= 0 && cureentDate.compareTo(deadline) <= 0){
                return false;
            }else{
                //如果当前时间小于上次执行时间就跳过
                if (cureentDate.compareTo(lastInspectDate) < 0 || cureentDate.compareTo(deadline) > 0) {
                    return true;
                }
            }
        }
        return false;
    }


    public Boolean isPasssWeekend(Date planDate) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(planDate);
        if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
            return true;
        }
        if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            return true;
        }
        return false;
    }
}
