/**
 * `lib/ds-alerts/edit.ts` の期待値表（指示書AX §3 表3。D15）
 *
 * ★表3 は指示書AX で導き、監督が正としたもの（監督判断 2026-10-19。§11 Q5）。変えないこと★
 *
 * | #  | 入力 | 期待 |
 * |----|------|------|
 * | S1 | `row`（unresolved・note null）、`updated`（同じ id・resolved・responded_at / resolved_at あり・note「確認済み」） | `row` の4項目だけ差し替え。他は `row` のまま |
 * | S2 | `updated.id !== row.id` | 例外 |
 * | S3 | summary {2,1,1}、1行が unresolved → resolved | {1,1,2} |
 * | S4 | 備考だけ変えた（状態は同じ） | summary は変わらない |
 * | S5 | 2行（unresolved → in_progress、in_progress → unresolved） | {2,1,1} のまま |
 * | S6 | `updated` が空の Map | 入力と同じ値（入力のオブジェクトを書き換えない） |
 */
import { describe, expect, it } from "vitest";
import { adjustDsAlertSummary, dsAlertWithResolution } from "@/lib/ds-alerts/edit";
import type { DsAlertSummary } from "@/lib/ds-alerts/query";
import type { DsAlert, ErrorReportItem } from "@/lib/types";

function alert(overrides: Partial<DsAlert> & Pick<DsAlert, "id">): DsAlert {
  return {
    alert_type: "disconnected",
    device_serial: "DFAS010001",
    facility_id: 3,
    facility_name: "テスト施設C",
    section_name: "1F売り場",
    detected_at: "2026-10-19T01:30:00+09:00",
    resolution_status: "unresolved",
    responded_at: null,
    resolved_at: null,
    note: null,
    ...overrides,
  };
}

/** PATCH /errors/{error_id}/status の応答。★DsAlert に無い項目はわざと row と違う値にする★（差し替えないことを見る） */
function updatedItem(overrides: Partial<ErrorReportItem> & Pick<ErrorReportItem, "id">): ErrorReportItem {
  return {
    detected_at: "2026-10-01T00:00:00+09:00",
    facility_id: 99,
    facility_name: "別の施設",
    serial_number: "OTHER",
    error_type: "D-S_CONTROL_FAILURE",
    error_level: "CRITICAL",
    clean_timetable_id: null,
    schedule_link: "none",
    precheck_minutes: null,
    resolution_status: "unresolved",
    responded_at: null,
    resolved_at: null,
    note: null,
    // エラー内容（指示書BD §3-2）。★DsAlert には無い項目★（D-Sec の行は選べない）
    error_list_id: null,
    error_list: null,
    error_list_selectable: false,
    ...overrides,
  };
}

describe("dsAlertWithResolution（表3 S1・S2）", () => {
  it("S1: 4項目だけ差し替え、他は row のまま", () => {
    const row = alert({ id: "1000004" });
    const updated = updatedItem({
      id: "1000004",
      resolution_status: "resolved",
      responded_at: "2026-10-19T09:00:00+09:00",
      resolved_at: "2026-10-19T09:30:00+09:00",
      note: "確認済み",
    });
    expect(dsAlertWithResolution(row, updated)).toEqual({
      ...row,
      resolution_status: "resolved",
      responded_at: "2026-10-19T09:00:00+09:00",
      resolved_at: "2026-10-19T09:30:00+09:00",
      note: "確認済み",
    });
  });

  it("S1: 入力の row を書き換えない", () => {
    const row = alert({ id: "1" });
    const snapshot = { ...row };
    dsAlertWithResolution(row, updatedItem({ id: "1", resolution_status: "resolved" }));
    expect(row).toEqual(snapshot);
  });

  it("★S2: id が違えば例外（呼び出しの誤り）★", () => {
    expect(() => dsAlertWithResolution(alert({ id: "1" }), updatedItem({ id: "2" }))).toThrow();
  });
});

describe("adjustDsAlertSummary（表3 S3〜S6）", () => {
  const SUMMARY: DsAlertSummary = { unresolved: 2, in_progress: 1, resolved: 1 };
  const BEFORE: DsAlert[] = [
    alert({ id: "a", resolution_status: "unresolved" }),
    alert({ id: "b", resolution_status: "unresolved" }),
    alert({ id: "c", resolution_status: "in_progress" }),
    alert({ id: "d", resolution_status: "resolved" }),
  ];

  it("S3: 1行が unresolved → resolved → {1,1,2}", () => {
    const updated = new Map([["a", { ...BEFORE[0], resolution_status: "resolved" as const }]]);
    expect(adjustDsAlertSummary(SUMMARY, BEFORE, updated)).toEqual({ unresolved: 1, in_progress: 1, resolved: 2 });
  });

  it("S4: 備考だけ変えた（状態は同じ）→ 変わらない", () => {
    const updated = new Map([["b", { ...BEFORE[1], note: "備考だけ" }]]);
    expect(adjustDsAlertSummary(SUMMARY, BEFORE, updated)).toEqual(SUMMARY);
  });

  it("S5: unresolved → in_progress と in_progress → unresolved → {2,1,1} のまま", () => {
    const updated = new Map([
      ["a", { ...BEFORE[0], resolution_status: "in_progress" as const }],
      ["c", { ...BEFORE[2], resolution_status: "unresolved" as const }],
    ]);
    expect(adjustDsAlertSummary(SUMMARY, BEFORE, updated)).toEqual({ unresolved: 2, in_progress: 1, resolved: 1 });
  });

  it("★S6: updated が空 → 入力と同じ値・入力のオブジェクトを書き換えない★", () => {
    const summary = { ...SUMMARY };
    const result = adjustDsAlertSummary(summary, BEFORE, new Map());
    expect(result).toEqual(SUMMARY);
    expect(summary).toEqual(SUMMARY);
  });

  it("★入力の summary を書き換えない（状態が変わったとき）★", () => {
    const summary = { ...SUMMARY };
    adjustDsAlertSummary(summary, BEFORE, new Map([["a", { ...BEFORE[0], resolution_status: "resolved" as const }]]));
    expect(summary).toEqual(SUMMARY);
  });
});
