package jnpf.model.cultivate.dto.learn;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.unit.DataUnit;
import cn.hutool.core.util.StrUtil;
import jnpf.model.cultivate.po.learn.*;
import jnpf.valid.ValidUpdate;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.time.LocalTime;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 学习任务信息
 * @Author: peng.hao
 * @create: 2024/9/9:13:58
 */
@Data
public class FtbCultivateLearnTaskInfoDto {

    /**主键id*/
    @NotBlank(message = "任务主键不能为空", groups = ValidUpdate.class)
    private String id;

    /** 任务分类主键id */
    @NotBlank(message = "任务分类不能为空")
    private String taskClass;

    /** 任务名称 */
    @NotBlank(message = "任务名称不能为空")
    @Size(max = 20, message = "任务名称长度不能超过20")
    private String taskName;

    /** 任务类型(0,长期,1限时) */
    @NotNull(message = "任务类型不能为空")
    private Integer taskType;

    /** 任务限时开始时间 */
    private Date timeLimitStartTime;

    /** 任务限时结束时间 */
    private Date timeLimitEndTime;

    /** 学员限时完成(0,限时,1不限时) */
    @NotNull(message = "学员限时完成不能为空")
    private Integer studentTimeCompletion;

    /** 学员限时完成单位(0,天,1,小时) */
    private Integer timeCompletionUnit;

    /**
     * 限时完成数值(365天,23小时)
     */
    private Integer timeCompletionDays;

    /** 任务分配规则(1,指定成员,2指定组织,3指定岗位,4自定义) */
    @NotNull(message = "任务分配规则不能为空")
    private Integer assignmentRule;

    /** 任务分配规则关联id(逗号分割) */
    private String associationIds;

    /** 自定义员工入职(期限开始天数) */
    private Integer startEntryPeriod;

    /** 自定义员工入职(期限结束天数) */
    private Integer endEntryPeriod;

    /***************************************任务分配***********************************************/
    /**任务分配用户id集合*/
    private List<String> userIds;

    /**************************************提醒规则************************************************/
    /** 开启任务开始提醒(0否,1是) */
    private Integer taskStartReminder;

    /** 开启定时提醒(0否,1是) */
    private Integer taskEndReminder;

    /**
     * 每天定时发送消息时间,HH:MM格式
     */
    private String perInterval;

    /**
     * 是否保存并发布，0保存，1保存并发布
     */
    private Integer whetherPublish;

    /** 是否考试鉴定合格才完成任务，1-是  0-否 */
    @NotNull(message = "规则考试鉴定合格才完成任务不能为null")
    private Integer isPassComplete;

    /**课程列表***/
    @NotNull(message = "课程列表不能为空")
    @Size(min = 1, message = "请勾选至少一个课程")
    private List<FtbCultivateLearnTaskCourseInfoDto> courseList;

    /***考试***/
    private FtbCultivateLearnTaskExamInfoDto examList;

    /***鉴定***/
    private FtbCultivateLearnTaskIdentificationInfoDto identificationList;

    /***证书***/
    private FtbCultivateLearnTaskCertificateInfoDto certificateList;


    public void beforeCheck() {
        // 前置校验
        Date now = new Date();
        if (taskType == 1 && (Objects.isNull(timeLimitStartTime) || Objects.isNull(timeLimitEndTime))) {
            throw new RuntimeException("限时任务未选择开始时间和结束时间");
        }
        if (taskType == 1 && now.after(timeLimitEndTime)) {
            throw new RuntimeException("任务结束时间不能晚于当前时间");
        }
        if (studentTimeCompletion == 0 && Objects.isNull(timeCompletionUnit)) {
            throw new RuntimeException("学员限时完成的限时任务单位不能为空");
        }
        if (studentTimeCompletion == 0 && timeCompletionUnit == 0 && timeCompletionDays > 365) {
            throw new RuntimeException("限时任务单位选“天”数字最大限制365");
        }
        if (studentTimeCompletion == 0 && timeCompletionUnit == 1 && timeCompletionDays > 23) {
            throw new RuntimeException("限时任务单位选“小时”数字最大限制23");
        }
        if (taskType == 1 && studentTimeCompletion == 0 && timeCompletionUnit == 0 &&
                DateUtil.between(timeLimitStartTime, timeLimitEndTime, DateUnit.DAY) < timeCompletionDays) {
            throw new RuntimeException("限时任务开始时间和结束时间的相差天数不能小于限时任务天数");
        }
        if (taskType == 1 && studentTimeCompletion == 0 && timeCompletionUnit == 1 &&
                DateUtil.between(timeLimitStartTime, timeLimitEndTime, DateUnit.HOUR) < timeCompletionDays) {
            throw new RuntimeException("限时任务开始时间和结束时间的相差小时不能小于限时任务天数");
        }
        if (assignmentRule == 4 && (Objects.isNull(startEntryPeriod) || Objects.isNull(endEntryPeriod))) {
            throw new RuntimeException("任务分配自定义新员工入职天数必填");
        }
        if (assignmentRule == 1 && CollUtil.isEmpty(userIds)) {
            throw new RuntimeException("任务分配指定用户成员不能为空");
        }
        if ((assignmentRule == 2 || assignmentRule == 3) && StrUtil.isEmpty(associationIds)) {
            throw new RuntimeException("指定组织或指定岗位任务分配关联数据不能为空");
        }
        // 至少一门必修课程
        if (courseList.stream().noneMatch(course -> course.getIsRequired() == 0)) {
            throw new RuntimeException("至少一门必修课程");
        }

        if (Objects.nonNull(examList)) {
            examList.setIsPassComplete(isPassComplete);
        }
        // 任务鉴定
        if (Objects.nonNull(identificationList)) {
            identificationList.setIsPassComplete(isPassComplete);
        }
        //限时任务 且 开启定时提醒
        if (taskEndReminder == 1 &&  StringUtils.isEmpty(perInterval)){
            throw new RuntimeException("每天定时发送消息时间不能为空");
        }
        //限时任务 且 开启定时提醒
        if (taskEndReminder == 1 && taskType == 1 && DateUtil.between(timeLimitStartTime, timeLimitEndTime, DateUnit.HOUR) < 24) {
            String startDayStr = DateUtil.format(timeLimitStartTime, "yyyy-MM-dd");
            String endDayStr = DateUtil.format(timeLimitEndTime, "yyyy-MM-dd");

            if (startDayStr.equals(endDayStr)) {
                String perIntervalStr = startDayStr + " " + perInterval;
                Date perDate = DateUtil.parse(perIntervalStr, "yyyy-MM-dd HH:mm");
                if (perDate.before(timeLimitStartTime) || perDate.after(timeLimitEndTime)) {
                    throw new RuntimeException("每天定时提醒时间不在任务开始和结束时间范围内");
                }
            } else {

                String perIntervalStr = startDayStr + " " + perInterval;
                Date perDate = DateUtil.parse(perIntervalStr, "yyyy-MM-dd HH:mm");
//                if (perDate.before(timeLimitStartTime)) {
//                    throw new RuntimeException("每天定时提醒时间不在任务开始和结束时间范围内");
//                }
//                String perIntervalStr1 = endDayStr + " " + perInterval;
//                Date perDate1 = DateUtil.parse(perIntervalStr1, "yyyy-MM-dd HH:mm");
//                if (timeLimitEndTime.after(perDate1)) {
//                    throw new RuntimeException("每天定时提醒时间不在任务开始和结束时间范围内");
//                }
                int compareStart = DateUtil.compare(perDate, timeLimitStartTime, "HH:mm");
                int compareEnd = DateUtil.compare(perDate, timeLimitEndTime, "HH:mm");
                if (compareStart < 0 && compareEnd > 0) {
                    throw new RuntimeException("每天定时提醒时间不在任务开始和结束时间范围内");
                }

            }
        }
    }


    public FtbCultivateLearnTask convertFtbCultivateLearnTask(FtbCultivateLearnTaskInfoDto taskInfoDto) {
        if (taskInfoDto == null) {
            return null;
        }
        Date now = new Date();
        FtbCultivateLearnTask ftbCultivateLearnTask = new FtbCultivateLearnTask();
        ftbCultivateLearnTask.setTaskClass(taskInfoDto.getTaskClass());
        ftbCultivateLearnTask.setTaskName(taskInfoDto.getTaskName());
        ftbCultivateLearnTask.setTaskType(taskInfoDto.getTaskType());
        ftbCultivateLearnTask.setTimeLimitStartTime(taskInfoDto.getTimeLimitStartTime());
        ftbCultivateLearnTask.setTimeLimitEndTime(taskInfoDto.getTimeLimitEndTime());
        ftbCultivateLearnTask.setStudentTimeCompletion(taskInfoDto.getStudentTimeCompletion());
        ftbCultivateLearnTask.setTimeCompletionUnit(taskInfoDto.getTimeCompletionUnit());
        ftbCultivateLearnTask.setTimeCompletionDays(taskInfoDto.getTimeCompletionDays());
        ftbCultivateLearnTask.setAssignmentRule(taskInfoDto.getAssignmentRule());
        ftbCultivateLearnTask.setAssociationIds(taskInfoDto.getAssociationIds());
        ftbCultivateLearnTask.setStartEntryPeriod(taskInfoDto.getStartEntryPeriod());
        ftbCultivateLearnTask.setEndEntryPeriod(taskInfoDto.getEndEntryPeriod());
        ftbCultivateLearnTask.setIsPassComplete(taskInfoDto.getIsPassComplete());
        // 发布状态确定，长期任务则根据保存状态区分，限时任务，根据时间进行计算
        if (whetherPublish == 0) {
            ftbCultivateLearnTask.setStatus(0);
            return ftbCultivateLearnTask;
        }
        ftbCultivateLearnTask.setStatus(1);
        if (taskType == 0) {
            ftbCultivateLearnTask.setStatus(2);
            return ftbCultivateLearnTask;
        }
        if (taskType == 1 && now.after(timeLimitStartTime)) {
            ftbCultivateLearnTask.setStatus(2);
        }
        return ftbCultivateLearnTask;
    }

    public FtbCultivateLearnTaskReminderRule convertTaskReminderRule(FtbCultivateLearnTaskInfoDto taskInfoDto) {
        FtbCultivateLearnTaskReminderRule ftbCultivateLearnTaskReminderRule = new FtbCultivateLearnTaskReminderRule();
        ftbCultivateLearnTaskReminderRule.setTaskStartReminder(taskInfoDto.getTaskStartReminder());
        ftbCultivateLearnTaskReminderRule.setTaskEndReminder(taskInfoDto.getTaskEndReminder());
        ftbCultivateLearnTaskReminderRule.setPerInterval(taskInfoDto.getPerInterval());
        return ftbCultivateLearnTaskReminderRule;
    }

    public FtbCultivateLearnTaskCertificate convertFtbCultivateLearnTaskCertificate(FtbCultivateLearnTaskInfoDto taskInfoDto) {
        FtbCultivateLearnTaskCertificate ftbCultivateLearnTaskCertificate = new FtbCultivateLearnTaskCertificate();
        ftbCultivateLearnTaskCertificate.setCertificateId(taskInfoDto.getCertificateList().getCertificateId());
        ftbCultivateLearnTaskCertificate.setIdentificationRule(taskInfoDto.getCertificateList().getIdentificationRule());
        ftbCultivateLearnTaskCertificate.setExamRule(taskInfoDto.getCertificateList().getExamRule());
        return ftbCultivateLearnTaskCertificate;
    }

    public FtbCultivateLearnTaskIdentification convertFtbCultivateLearnTaskIdentification(FtbCultivateLearnTaskInfoDto taskInfoDto) {
        FtbCultivateLearnTaskIdentification ftbCultivateLearnTaskIdentification = new FtbCultivateLearnTaskIdentification();
        ftbCultivateLearnTaskIdentification.setIdentificationId(taskInfoDto.getIdentificationList().getIdentificationId());
        ftbCultivateLearnTaskIdentification.setIdentificationRule(taskInfoDto.getIdentificationList().getIdentificationRule());
        ftbCultivateLearnTaskIdentification.setIsPassComplete(isPassComplete);
        return ftbCultivateLearnTaskIdentification;
    }

    public FtbCultivateLearnTaskExam convertFtbCultivateLearnTaskExam(FtbCultivateLearnTaskInfoDto taskInfoDto) {
        FtbCultivateLearnTaskExam ftbCultivateLearnTaskExam = new FtbCultivateLearnTaskExam();
        ftbCultivateLearnTaskExam.setExamId(taskInfoDto.getExamList().getExamId());
        ftbCultivateLearnTaskExam.setIsPassComplete(isPassComplete);
        return ftbCultivateLearnTaskExam;
    }

}
