package jnpf.attendance.schedule;

import java.io.Serializable;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 同一员工在的自然日内已占位班段（左闭右开分钟坐标），用于禁止<strong>时间重叠</strong>。
 * <p>
 * 与 {@link StaffAssignmentDayLedger} 分工：账本管固定 vs 划线互斥与同 logical key；本类管「不能同时出现在两个重叠时段」。
 */
public final class StaffAssignmentIntervalLedger implements Serializable {

    private final Map<String, Map<LocalDate, List<int[]>>> byEmployeeThenDay = new HashMap<>();

    /** 左闭右开区间 [startInclusive, endExclusive) 是否与已占位区间重叠。 */
    public boolean canAssign(
            String employeeId, LocalDate day, int startInclusiveMinute, int endExclusiveMinute) {
        if (employeeId == null || employeeId.trim().isEmpty() || day == null) {
            return false;
        }
        if (endExclusiveMinute <= startInclusiveMinute) {
            return false;
        }
        String id = employeeId.trim();
        for (int[] iv : intervals(id, day)) {
            if (intervalsOverlap(iv[0], iv[1], startInclusiveMinute, endExclusiveMinute)) {
                return false;
            }
        }
        return true;
    }

    public void mark(String employeeId, LocalDate day, int startInclusiveMinute, int endExclusiveMinute) {
        if (employeeId == null || employeeId.trim().isEmpty() || day == null) {
            return;
        }
        if (endExclusiveMinute <= startInclusiveMinute) {
            return;
        }
        intervals(employeeId.trim(), day).add(new int[] {startInclusiveMinute, endExclusiveMinute});
    }

    private List<int[]> intervals(String employeeId, LocalDate day) {
        return byEmployeeThenDay
                .computeIfAbsent(employeeId, k -> new HashMap<>())
                .computeIfAbsent(day, d -> new ArrayList<>());
    }

    private static boolean intervalsOverlap(int a0, int a1, int b0, int b1) {
        return a0 < b1 && b0 < a1;
    }
}
