package jnpf.attendance.service.impl.preschedule;

import jnpf.attendance.mapper.AttendanceGroupMapper;
import jnpf.exception.HandleException;
import jnpf.exception.QueryException;
import jnpf.model.attendance.vo.scheduling.PreScheduleTableRowVo;
import jnpf.model.attendance.vo.scheduling.PreScheduleTableVo;
import jnpf.util.StringUtil;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List;

/**
 * 预排班主表提交保存请求校验。
 */
public final class PreScheduleSaveValidator {

    private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ISO_LOCAL_DATE;

    private PreScheduleSaveValidator() {
    }

    public static ValidatedPreScheduleSave validate(
            PreScheduleTableVo vo, AttendanceGroupMapper attendanceGroupMapper)
            throws HandleException, QueryException {
        if (vo == null) {
            throw new HandleException("请求体不能为空");
        }
        String groupId = vo.getGroupId();
        if (StringUtil.isBlank(groupId)) {
            throw new HandleException("考勤组ID不能为空");
        }
        PreScheduleQueryValidator.assertAttendanceGroupExists(groupId.trim(), attendanceGroupMapper);

        List<PreScheduleTableRowVo> rows = vo.getRows();
        if (rows == null || rows.isEmpty()) {
            throw new HandleException("主表行不能为空");
        }

        LocalDate startDate = null;
        LocalDate endDate = null;
        for (PreScheduleTableRowVo row : rows) {
            if (row == null) {
                throw new HandleException("主表行存在空项");
            }
            LocalDate day = parseDate(row.getDate(), "rows.date");
            if (startDate == null || day.isBefore(startDate)) {
                startDate = day;
            }
            if (endDate == null || day.isAfter(endDate)) {
                endDate = day;
            }
        }

        ValidatedPreScheduleSave validated = new ValidatedPreScheduleSave();
        validated.setGroupId(groupId.trim());
        validated.setStartDate(startDate);
        validated.setEndDate(endDate);
        validated.setTable(vo);
        return validated;
    }

    /** 排班区间键片段：{@code yyyy-MM-dd_yyyy-MM-dd}。 */
    public static String formatDateRangeKey(LocalDate startDate, LocalDate endDate) {
        return startDate.format(DATE_FMT) + "_" + endDate.format(DATE_FMT);
    }

    private static LocalDate parseDate(String text, String fieldLabel) throws HandleException {
        if (StringUtil.isBlank(text)) {
            throw new HandleException(fieldLabel + "不能为空");
        }
        try {
            return LocalDate.parse(text.trim(), DATE_FMT);
        } catch (DateTimeParseException ex) {
            throw new HandleException(fieldLabel + "格式须为 yyyy-MM-dd");
        }
    }

    /**
     * 保存校验通过后的上下文。
     */
    public static final class ValidatedPreScheduleSave {
        private String groupId;
        private LocalDate startDate;
        private LocalDate endDate;
        private PreScheduleTableVo table;

        public String getGroupId() {
            return groupId;
        }

        public void setGroupId(String groupId) {
            this.groupId = groupId;
        }

        public LocalDate getStartDate() {
            return startDate;
        }

        public void setStartDate(LocalDate startDate) {
            this.startDate = startDate;
        }

        public LocalDate getEndDate() {
            return endDate;
        }

        public void setEndDate(LocalDate endDate) {
            this.endDate = endDate;
        }

        public PreScheduleTableVo getTable() {
            return table;
        }

        public void setTable(PreScheduleTableVo table) {
            this.table = table;
        }
    }
}
