package jnpf.model.cultivate.v2.task.req;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import jnpf.model.cultivate.dto.learn.FtbCultivateLearnTaskInfoDto;
import jnpf.model.cultivate.po.learn.FtbCultivateLearnTask;
import jnpf.model.cultivate.po.learn.FtbCultivateLearnTaskReminderRule;
import jnpf.model.cultivate.v2.task.vo.V2CultivateLearnTaskPhaseVo;
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.util.Date;
import java.util.List;
import java.util.Objects;


@Data
public class V2CultivateTaskSaveReq {

    /**
     * 主键id
     */
    private String id;

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

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

    /**
     * 任务描述
     */
    @NotBlank(message = "任务描述不能为空")
    @Size(max = 100, message = "任务描述长度不能超过100")
    private String description;


    /**
     * 任务封面Id
     */
    @NotBlank(message = "封面不能为空")
    private String coverId;

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

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

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


    /**
     * 学员限时完成(0,限时,1不限时)
     */
    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 = 0;

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

    /**
     * 自定义分类类型: 0-新员工 1-岗领
     */
    private Integer customAssignType;

    /**
     * 自定义岗位IDS
     */
    private String customAssignPostIds;

    /***************************************任务分配***********************************************/
    /**
     * 任务分配用户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;

    private List<V2CultivateLearnTaskPhaseVo> phase;


    public void beforeCheck() {
        // 前置校验
        Date now = new Date();
        if (taskType == 1 && (Objects.isNull(timeLimitStartTime) || Objects.isNull(timeLimitEndTime))) {
            throw new RuntimeException("限时任务未选择开始时间和结束时间");
        }
        if (taskType == 1 && timeLimitStartTime.after(timeLimitEndTime)) {
            throw new RuntimeException("任务结束时间不能晚于开始时间");
        }
        if (taskType == 1 && now.after(timeLimitEndTime)) {
            throw new RuntimeException("任务结束时间不能晚于当前时间");
        }
        if (taskType == 0 && (studentTimeCompletion == 0 && Objects.isNull(timeCompletionUnit))) {
            throw new RuntimeException("学员限时完成的限时任务单位不能为空");
        }
        if (taskType == 0 && studentTimeCompletion == 0 && timeCompletionUnit == 0 && timeCompletionDays > 365) {
            throw new RuntimeException("限时任务单位选“天”数字最大限制365");
        }
        if (taskType == 0 && 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 && customAssignType == 0 && (Objects.isNull(startEntryPeriod) || Objects.isNull(endEntryPeriod))) {
            throw new RuntimeException("任务分配-自定义新员工入职天数必填");
        }
        if (assignmentRule == 4 && customAssignType == 1 && StringUtils.isNotEmpty(customAssignPostIds) && (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 (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");
                int compareStart = DateUtil.compare(perDate, timeLimitStartTime, "HH:mm");
                int compareEnd = DateUtil.compare(perDate, timeLimitEndTime, "HH:mm");
                if (compareStart < 0 && compareEnd > 0) {
                    throw new RuntimeException("每天定时提醒时间不在任务开始和结束时间范围内");
                }

            }
        }
        if (CollUtil.isEmpty(phase)) {
            throw new RuntimeException("请添加任务阶段");
        }
        beforeCheckPhase(phase);
    }

    private void beforeCheckPhase(List<V2CultivateLearnTaskPhaseVo> phaseList) {
        for (int i = 0; i < phaseList.size(); i++) {
            V2CultivateLearnTaskPhaseVo phaseVo = phaseList.get(i);
            if(CollUtil.isEmpty(phaseVo.getCourseList())){
                throw new RuntimeException("第"+(i+1)+"阶段未配置课程");
            }
        }

    }


    public FtbCultivateLearnTask convertFtbCultivateLearnTask(V2CultivateTaskSaveReq taskInfoDto) {
        Date now = new Date();
        FtbCultivateLearnTask ftbCultivateLearnTask = new FtbCultivateLearnTask();
        ftbCultivateLearnTask.setId(taskInfoDto.getId());
        ftbCultivateLearnTask.setTaskClass(taskInfoDto.getTaskClass());
        ftbCultivateLearnTask.setTaskName(taskInfoDto.getTaskName());
        ftbCultivateLearnTask.setDescription(taskInfoDto.getDescription());
        ftbCultivateLearnTask.setCoverId(taskInfoDto.getCoverId());
        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(0);
        ftbCultivateLearnTask.setEndEntryPeriod(taskInfoDto.getEndEntryPeriod());
        ftbCultivateLearnTask.setCustomAssignType(taskInfoDto.getCustomAssignType());
        ftbCultivateLearnTask.setCustomAssignPostIds(taskInfoDto.getCustomAssignPostIds());
        ftbCultivateLearnTask.setEnableMark(0);
        // 发布状态确定，长期任务则根据保存状态区分，限时任务，根据时间进行计算
        if (whetherPublish == 0) {
            ftbCultivateLearnTask.setStatus(0);
            return ftbCultivateLearnTask;
        }
        // 已发布任务的状态计算
        if (taskType == 0) {
            // 长期任务：直接设置为进行中
            ftbCultivateLearnTask.setStatus(2);
            return ftbCultivateLearnTask;
        }
        // 限时任务：根据时间计算状态
        if (taskType == 1) {
            if (now.before(timeLimitStartTime)) {
                // 当前时间在开始时间之前：未开始
                ftbCultivateLearnTask.setStatus(1);
            } else if (now.after(timeLimitEndTime)) {
                // 当前时间在结束时间之后：已结束
                ftbCultivateLearnTask.setStatus(3);
            } else {
                // 当前时间在开始和结束时间之间：进行中
                ftbCultivateLearnTask.setStatus(2);
            }
        }
        return ftbCultivateLearnTask;
    }



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