// IMP-47B u11 — Frontend ai_repair_status notification surfacing.
//
// Scope (Stage 2 unit u11 contract):
//   1) loadRun → RunMeta.ai_repair_status exposes the u8 step20 payload.
//   2) formatAiRepairHumanReviewMessage(...) returns user-facing notification
//      text on the three failure axes (error / coverage_violated /
//      unsupported_kind) and returns null on success / no-AI paths.
//
// Pure-function unit test (no React Testing Library required — vitest is
// already in devDependencies; @testing-library/* is NOT installed). The
// Home.tsx wiring is a 2-line site that calls this helper after
// setRunMeta(...); covering the helper covers the user-visible message text
// directly without DOM rendering.
//
// File extension is `.tsx` per Stage 2 unit contract path; no JSX is required
// for these assertions but the extension allows future RTL-based tests to
// land here without renaming.

import { describe, it, expect } from "vitest";
import {
  formatAiRepairHumanReviewMessage,
  type AiRepairStatus,
} from "../src/services/designAgentApi";

const baseCounts = {
  total: 1,
  applied: 0,
  no_proposal: 0,
  no_zone_match: 0,
  unsupported_kind: 0,
  error: 0,
};

describe("formatAiRepairHumanReviewMessage (IMP-47B u11)", () => {
  it("returns null when ai_repair_status is null (legacy / pre-Step12 abort)", () => {
    expect(formatAiRepairHumanReviewMessage(null)).toBeNull();
    expect(formatAiRepairHumanReviewMessage(undefined)).toBeNull();
  });

  it("returns null when human_review_required=false (success / no-AI path)", () => {
    const ok: AiRepairStatus = {
      status: "ok",
      counts: { ...baseCounts, total: 0 },
      unsupported_kind_records: [],
      error_records: [],
      coverage_status: "ok",
      dropped_section_ids: [],
      human_review_required: false,
    };
    expect(formatAiRepairHumanReviewMessage(ok)).toBeNull();

    const applied: AiRepairStatus = {
      ...ok,
      status: "applied",
      counts: { ...baseCounts, total: 1, applied: 1 },
    };
    expect(formatAiRepairHumanReviewMessage(applied)).toBeNull();
  });

  it("surfaces AI call failures with count + frame/manual guidance", () => {
    const errored: AiRepairStatus = {
      status: "error",
      counts: { ...baseCounts, total: 2, error: 2 },
      unsupported_kind_records: [],
      error_records: [
        { unit_index: 0, source_section_ids: ["03-1"], error: "timeout" },
        { unit_index: 1, source_section_ids: ["03-2"], error: "validation" },
      ],
      coverage_status: "ok",
      dropped_section_ids: [],
      human_review_required: true,
    };
    const msg = formatAiRepairHumanReviewMessage(errored);
    expect(msg).not.toBeNull();
    expect(msg).toContain("AI 재구성 호출 실패");
    expect(msg).toContain("2");
    expect(msg).toContain("다른 frame 선택 또는 수동 편집 필요");
  });

  it("surfaces coverage violations with the dropped section ids", () => {
    const dropped: AiRepairStatus = {
      status: "coverage_violated",
      counts: { ...baseCounts, total: 1, applied: 1 },
      unsupported_kind_records: [],
      error_records: [],
      coverage_status: "violated",
      dropped_section_ids: ["03-2"],
      human_review_required: true,
    };
    const msg = formatAiRepairHumanReviewMessage(dropped);
    expect(msg).not.toBeNull();
    expect(msg).toContain("콘텐츠 누락");
    expect(msg).toContain("03-2");
    expect(msg).toContain("다른 frame 선택 또는 수동 편집 필요");
  });

  it("surfaces unsupported proposal kinds with the unsupported count", () => {
    const unsupported: AiRepairStatus = {
      status: "unsupported_kind",
      counts: { ...baseCounts, total: 1, unsupported_kind: 1 },
      unsupported_kind_records: [
        {
          unit_index: 0,
          source_section_ids: ["03-1"],
          apply_status: "unsupported_kind_for_reject_route:builder_options_patch",
        },
      ],
      error_records: [],
      coverage_status: "ok",
      dropped_section_ids: [],
      human_review_required: true,
    };
    const msg = formatAiRepairHumanReviewMessage(unsupported);
    expect(msg).not.toBeNull();
    expect(msg).toContain("AI 제안 형식 미지원");
    expect(msg).toContain("1");
    expect(msg).toContain("다른 frame 선택 또는 수동 편집 필요");
  });

  it("falls back to a generic human_review message on unknown status enums", () => {
    const future: AiRepairStatus = {
      status: "future_axis_not_yet_mapped",
      counts: { ...baseCounts, total: 0 },
      unsupported_kind_records: [],
      error_records: [],
      coverage_status: "ok",
      dropped_section_ids: [],
      human_review_required: true,
    };
    const msg = formatAiRepairHumanReviewMessage(future);
    expect(msg).not.toBeNull();
    expect(msg).toContain("human_review");
    expect(msg).toContain("future_axis_not_yet_mapped");
  });
});
