package jnpf.attendance.schedule;

import jnpf.model.attendance.vo.scheduling.LineSchedulingRuleVo;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 第八步：划线班次兜底参数（半小时为 1 格，2 小时=4 格）。
 */
public final class LineShiftCoverConfig implements Serializable {

    private final int minHalfHourSlots;
    private final int maxHalfHourSlots;
    /** 单日每岗位最多输出的划线班段个数（算法侧上限）。 */
    private final int maxLineSegmentsPerPostPerDay;

    public LineShiftCoverConfig(int minHalfHourSlots, int maxHalfHourSlots, int maxLineSegmentsPerPostPerDay) {
        if (minHalfHourSlots < 1 || maxHalfHourSlots < minHalfHourSlots || maxLineSegmentsPerPostPerDay < 1) {
            throw new IllegalArgumentException("invalid LineShiftCoverConfig");
        }
        this.minHalfHourSlots = minHalfHourSlots;
        this.maxHalfHourSlots = maxHalfHourSlots;
        this.maxLineSegmentsPerPostPerDay = maxLineSegmentsPerPostPerDay;
    }

    public static LineShiftCoverConfig defaults() {
        return new LineShiftCoverConfig(4, 8, 4);
    }

    /**
     * 从考勤组规则 VO 读取；未启用或值为 null 时使用默认 2h～4h、每岗每日最多 4 段。
     */
    public static LineShiftCoverConfig fromLineSchedulingRule(LineSchedulingRuleVo vo) {
        int minSlots = 4;
        int maxSlots = 8;
        int maxSeg = 4;
        if (vo != null) {
            if (Boolean.TRUE.equals(vo.getMinSingleSegmentHoursEnabled())
                    && vo.getMinSingleSegmentHoursValue() != null) {
                minSlots = Math.max(1, hoursToHalfHourSlots(vo.getMinSingleSegmentHoursValue(), RoundingMode.CEILING));
            }
            if (Boolean.TRUE.equals(vo.getMaxSingleSegmentHoursEnabled())
                    && vo.getMaxSingleSegmentHoursValue() != null) {
                maxSlots = Math.max(minSlots, vo.getMaxSingleSegmentHoursValue() * 2);
            }
            if (Boolean.TRUE.equals(vo.getMaxDailySegmentsEnabled()) && vo.getMaxDailySegmentsValue() != null) {
                maxSeg = Math.max(1, vo.getMaxDailySegmentsValue());
            }
        }
        return new LineShiftCoverConfig(minSlots, maxSlots, maxSeg);
    }

    private static int hoursToHalfHourSlots(BigDecimal hours, RoundingMode mode) {
        return hours.multiply(BigDecimal.valueOf(2)).setScale(0, mode).intValue();
    }

    public int getMinHalfHourSlots() {
        return minHalfHourSlots;
    }

    public int getMaxHalfHourSlots() {
        return maxHalfHourSlots;
    }

    public int getMaxLineSegmentsPerPostPerDay() {
        return maxLineSegmentsPerPostPerDay;
    }
}
