package jnpf.attendance.schedule;

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

/**
 * 第五步：半小时时间段 × 岗位的目标人数矩阵（行=时间段，列=岗位）。
 */
public final class HalfHourPostDemandMatrix implements Serializable {

    private final LocalDate scheduleDay;
    private final List<String> slotRangeLabelsOrdered;
    private final List<String> postIdsOrdered;
    /** slot → (post → target) */
    private final Map<String, Map<String, Integer>> targetBySlotThenPost;

    public HalfHourPostDemandMatrix(
            LocalDate scheduleDay,
            List<String> slotRangeLabelsOrdered,
            List<String> postIdsOrdered,
            Map<String, Map<String, Integer>> targetBySlotThenPost) {
        this.scheduleDay = Objects.requireNonNull(scheduleDay, "scheduleDay");
        this.slotRangeLabelsOrdered =
                Collections.unmodifiableList(new ArrayList<>(Objects.requireNonNull(slotRangeLabelsOrdered)));
        this.postIdsOrdered = Collections.unmodifiableList(new ArrayList<>(Objects.requireNonNull(postIdsOrdered)));
        Map<String, Map<String, Integer>> copy = new LinkedHashMap<>();
        for (Map.Entry<String, Map<String, Integer>> e : targetBySlotThenPost.entrySet()) {
            if (e.getKey() == null || e.getValue() == null) {
                continue;
            }
            copy.put(e.getKey(), Collections.unmodifiableMap(new LinkedHashMap<>(e.getValue())));
        }
        this.targetBySlotThenPost = Collections.unmodifiableMap(copy);
    }

    public LocalDate getScheduleDay() {
        return scheduleDay;
    }

    /** 按时间顺序排列的时间段标签（与 {@link #getPostIdsOrdered()} 构成矩阵行列）。 */
    public List<String> getSlotRangeLabelsOrdered() {
        return slotRangeLabelsOrdered;
    }

    /** 岗位 id 列顺序（表头）。 */
    public List<String> getPostIdsOrdered() {
        return postIdsOrdered;
    }

    public int getTarget(String slotRangeLabel, String postId) {
        if (slotRangeLabel == null || postId == null) {
            return 0;
        }
        Map<String, Integer> row = targetBySlotThenPost.get(slotRangeLabel);
        if (row == null) {
            return 0;
        }
        Integer v = row.get(postId);
        return v == null ? 0 : v;
    }

    public Map<String, Map<String, Integer>> getTargetBySlotThenPost() {
        return targetBySlotThenPost;
    }

    /** 便于日志：TSV 首行为 post 表头，后续每行 slot + 各岗位人数。 */
    public String toTsvTable() {
        StringBuilder sb = new StringBuilder();
        sb.append("时间段");
        for (String p : postIdsOrdered) {
            sb.append('\t').append(p);
        }
        sb.append('\n');
        for (String slot : slotRangeLabelsOrdered) {
            sb.append(slot);
            for (String p : postIdsOrdered) {
                sb.append('\t').append(getTarget(slot, p));
            }
            sb.append('\n');
        }
        return sb.toString();
    }

    @Override
    public String toString() {
        return "HalfHourPostDemandMatrix{scheduleDay="
                + scheduleDay
                + ", slots="
                + slotRangeLabelsOrdered.size()
                + ", posts="
                + postIdsOrdered.size()
                + '}';
    }
}
