package jnpf.attendance.schedule;

import java.io.Serializable;
import java.time.LocalDate;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/** 第六～八步：固定班候选、贪心覆盖、划线兜底后的汇总结果。 */
public final class ScheduleDemandCoverResult implements Serializable {

    private final LocalDate scheduleDay;
    private final Map<String, List<PostFixedShiftCandidate>> fixedCandidatesByPost;
    private final Map<String, FixedShiftCoverOutcome> fixedShiftCoverByPost;
    private final Map<String, List<LineShiftPick>> lineShiftPicksByPost;
    /** 每岗位、每半小时行序下，最终仍缺人数（≥0） */
    private final Map<String, int[]> remainingNeedByPostAfterLine;

    public ScheduleDemandCoverResult(
            LocalDate scheduleDay,
            Map<String, List<PostFixedShiftCandidate>> fixedCandidatesByPost,
            Map<String, FixedShiftCoverOutcome> fixedShiftCoverByPost,
            Map<String, List<LineShiftPick>> lineShiftPicksByPost,
            Map<String, int[]> remainingNeedByPostAfterLine) {
        this.scheduleDay = Objects.requireNonNull(scheduleDay, "scheduleDay");
        this.fixedCandidatesByPost = unmodifiableCopyNested(fixedCandidatesByPost);
        this.fixedShiftCoverByPost = unmodifiableCopyMap(fixedShiftCoverByPost);
        this.lineShiftPicksByPost = unmodifiableCopyNestedList(lineShiftPicksByPost);
        this.remainingNeedByPostAfterLine = unmodifiableCopyIntArrays(remainingNeedByPostAfterLine);
    }

    private static Map<String, List<PostFixedShiftCandidate>> unmodifiableCopyNested(
            Map<String, List<PostFixedShiftCandidate>> in) {
        Map<String, List<PostFixedShiftCandidate>> m = new LinkedHashMap<>();
        if (in != null) {
            for (Map.Entry<String, List<PostFixedShiftCandidate>> e : in.entrySet()) {
                if (e.getKey() == null || e.getValue() == null) {
                    continue;
                }
                m.put(e.getKey(), Collections.unmodifiableList(new java.util.ArrayList<>(e.getValue())));
            }
        }
        return Collections.unmodifiableMap(m);
    }

    private static Map<String, FixedShiftCoverOutcome> unmodifiableCopyMap(
            Map<String, FixedShiftCoverOutcome> in) {
        Map<String, FixedShiftCoverOutcome> m = new LinkedHashMap<>();
        if (in != null) {
            m.putAll(in);
        }
        return Collections.unmodifiableMap(m);
    }

    private static Map<String, List<LineShiftPick>> unmodifiableCopyNestedList(
            Map<String, List<LineShiftPick>> in) {
        Map<String, List<LineShiftPick>> m = new LinkedHashMap<>();
        if (in != null) {
            for (Map.Entry<String, List<LineShiftPick>> e : in.entrySet()) {
                if (e.getKey() == null || e.getValue() == null) {
                    continue;
                }
                m.put(e.getKey(), Collections.unmodifiableList(new java.util.ArrayList<>(e.getValue())));
            }
        }
        return Collections.unmodifiableMap(m);
    }

    private static Map<String, int[]> unmodifiableCopyIntArrays(Map<String, int[]> in) {
        Map<String, int[]> m = new LinkedHashMap<>();
        if (in != null) {
            for (Map.Entry<String, int[]> e : in.entrySet()) {
                if (e.getKey() == null || e.getValue() == null) {
                    continue;
                }
                m.put(e.getKey(), e.getValue().clone());
            }
        }
        return Collections.unmodifiableMap(m);
    }

    public LocalDate getScheduleDay() {
        return scheduleDay;
    }

    public Map<String, List<PostFixedShiftCandidate>> getFixedCandidatesByPost() {
        return fixedCandidatesByPost;
    }

    public Map<String, FixedShiftCoverOutcome> getFixedShiftCoverByPost() {
        return fixedShiftCoverByPost;
    }

    public Map<String, List<LineShiftPick>> getLineShiftPicksByPost() {
        return lineShiftPicksByPost;
    }

    public Map<String, int[]> getRemainingNeedByPostAfterLine() {
        return remainingNeedByPostAfterLine;
    }
}
