package jnpf.attendance.schedule;

import java.io.Serializable;
import java.util.Objects;

/**
 * 第四步「时间段 + 岗位」稳健目标人数：波动小用中位数，波动大用 P75。
 */
public final class SlotPostRobustTargetConfig implements Serializable {

    /**
     * 当 {@code max(samples) - min(samples) <= maxMinusMinUseMedianThreshold} 时取<strong>中位数</strong>，否则取<strong>P75</strong>（最近序位法）。
     * 默认 1：如 2,2,2,2,2（极差 0）用中位数；如 1,2,2,3,4（极差 3）用 P75。
     */
    private final int maxMinusMinUseMedianThreshold;

    /**
     * 为 true 时：对每个相似历史日若该日无 (时间段,岗位) 样本则按 0 计入，再算中位数/P75；
     * 为 false 时：仅使用在原始行中出现过的历史日样本（样本量可能少于相似日个数）。
     */
    private final boolean imputeZeroForMissingSimilarDays;

    public SlotPostRobustTargetConfig(int maxMinusMinUseMedianThreshold, boolean imputeZeroForMissingSimilarDays) {
        if (maxMinusMinUseMedianThreshold < 0) {
            throw new IllegalArgumentException("maxMinusMinUseMedianThreshold must be >= 0");
        }
        this.maxMinusMinUseMedianThreshold = maxMinusMinUseMedianThreshold;
        this.imputeZeroForMissingSimilarDays = imputeZeroForMissingSimilarDays;
    }

    public static SlotPostRobustTargetConfig defaults() {
        return new SlotPostRobustTargetConfig(1, false);
    }

    public int getMaxMinusMinUseMedianThreshold() {
        return maxMinusMinUseMedianThreshold;
    }

    public boolean isImputeZeroForMissingSimilarDays() {
        return imputeZeroForMissingSimilarDays;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        SlotPostRobustTargetConfig that = (SlotPostRobustTargetConfig) o;
        return maxMinusMinUseMedianThreshold == that.maxMinusMinUseMedianThreshold
                && imputeZeroForMissingSimilarDays == that.imputeZeroForMissingSimilarDays;
    }

    @Override
    public int hashCode() {
        return Objects.hash(maxMinusMinUseMedianThreshold, imputeZeroForMissingSimilarDays);
    }
}
