package jnpf.attendance.schedule;

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

/**
 * 由需求覆盖结果（固定班贪心 + 划线兜底）与人员池推导出的「可核对」排班行：日期、班次标签、人员。
 *
 * <p>说明：此为在 {@link ScheduleDemandCoverResult} 之上的<strong>派生视图</strong>，用于报表/测试对账；
 * 人员分配采用专岗优先、再通岗、同日时段不重叠的贪心规则，与生产第九/十步完整规则可能不同。
 */
public final class FinalScheduleRosterLine implements Serializable {

    public static final String KIND_FIXED = "FIXED";
    public static final String KIND_LINE = "LINE";

    private final LocalDate scheduleDay;
    private final String postId;
    private final String kind;
    /** 展示用班次标签（固定班为归一化区间；划线为时段标签或分钟区间格式化）。 */
    private final String shiftLabel;
    private final int startMinuteInclusive;
    private final int endMinuteExclusive;
    private final String employeeUserId;

    public FinalScheduleRosterLine(
            LocalDate scheduleDay,
            String postId,
            String kind,
            String shiftLabel,
            int startMinuteInclusive,
            int endMinuteExclusive,
            String employeeUserId) {
        this.scheduleDay = Objects.requireNonNull(scheduleDay, "scheduleDay");
        this.postId = postId == null ? "" : postId;
        this.kind = kind == null ? "" : kind;
        this.shiftLabel = shiftLabel == null ? "" : shiftLabel;
        this.startMinuteInclusive = startMinuteInclusive;
        this.endMinuteExclusive = endMinuteExclusive;
        this.employeeUserId = employeeUserId == null ? "" : employeeUserId;
    }

    public LocalDate getScheduleDay() {
        return scheduleDay;
    }

    public String getPostId() {
        return postId;
    }

    public String getKind() {
        return kind;
    }

    public String getShiftLabel() {
        return shiftLabel;
    }

    public int getStartMinuteInclusive() {
        return startMinuteInclusive;
    }

    public int getEndMinuteExclusive() {
        return endMinuteExclusive;
    }

    public String getEmployeeUserId() {
        return employeeUserId;
    }

    /** 与 {@link HalfHourSlotLabel#formatMinuteRange} 一致的可读时段。 */
    public String getTimeRangeLabel() {
        return HalfHourSlotLabel.formatMinuteRange(startMinuteInclusive, endMinuteExclusive);
    }

    @Override
    public String toString() {
        return "FinalScheduleRosterLine{"
                + "day=" + scheduleDay
                + ", post=" + postId
                + ", kind=" + kind
                + ", shift=" + shiftLabel
                + ", time=" + getTimeRangeLabel()
                + ", user=" + employeeUserId
                + '}';
    }
}
