import { describe, expect, it } from "vitest";

import { selectAreaRowsForLog } from "@/lib/clean-logs/areas";
import { filterFixtureAreaCompletions } from "@/lib/db/fixture-area-completions";
import { areaCompletions } from "@/lib/fixtures";
import type { AreaCompletionDbQuery } from "@/lib/types";

/**
 * 指示書AC ★段階3★ — fixtures 版 `areaCompletions()` も同じ引数を受け取り、同じ結果を返す。
 *
 * ★★`USE_FIXTURES` の true/false で件数が変わってはいけない★★（指示書AC 禁止事項6）。
 * ★★絞り込み規則の「正」は `selectAreaRowsForLog()`★★ — ★ここはその写し★ なので、
 *   ★★等価であること（SQL版 ＝ 全件版 + 純粋関数）をここで固定する★★（G-3）。
 *
 * ★fixtures の**既存の値**は変更していない★（禁止事項5）— ここは読むだけ。
 */

const ALL: AreaCompletionDbQuery = { facility_id: null, date: null };

/** fixtures に実在する「施設 × 日付」の組を1つ選ぶ（実行日相対で作られるため固定値にしない） */
const sample = areaCompletions[0];

describe("filterFixtureAreaCompletions（指示書AC 段階3）", () => {
  it("#1 範囲なし（全部 null）→ fixtures の全件", () => {
    expect(filterFixtureAreaCompletions(areaCompletions, ALL)).toHaveLength(
      areaCompletions.length
    );
  });

  it("★★施設 + 日付 → `selectAreaRowsForLog()` と完全一致★★（等価テスト）", () => {
    const target = { facility_id: sample.facility_id, date: sample.date };
    expect(filterFixtureAreaCompletions(areaCompletions, target)).toEqual(
      selectAreaRowsForLog(areaCompletions, target)
    );
  });

  it("★★同じ施設・同じ日の全エリアが返る★★（`clean_log_id` で絞らないこと。指示書Z 決定1）", () => {
    const rows = filterFixtureAreaCompletions(areaCompletions, {
      facility_id: sample.facility_id,
      date: sample.date,
    });
    expect(rows.length).toBeGreaterThan(0);
    expect(rows).toContainEqual(sample);
    // ★その施設・その日の行が1つも落ちていないこと★
    expect(rows).toEqual(
      areaCompletions.filter(
        (r) => r.facility_id === sample.facility_id && r.date === sample.date
      )
    );
  });

  it("施設だけ / 日付だけでも絞れる（AND が効く）", () => {
    const byFacility = filterFixtureAreaCompletions(areaCompletions, {
      facility_id: sample.facility_id,
      date: null,
    });
    expect(byFacility.every((r) => r.facility_id === sample.facility_id)).toBe(true);

    const byDate = filterFixtureAreaCompletions(areaCompletions, {
      facility_id: null,
      date: sample.date,
    });
    expect(byDate.every((r) => r.date === sample.date)).toBe(true);
    expect(byDate.length).toBeGreaterThanOrEqual(
      filterFixtureAreaCompletions(areaCompletions, {
        facility_id: sample.facility_id,
        date: sample.date,
      }).length
    );
  });

  it("存在しない施設・日付 → 0件（★`null` と取り違えていない★）", () => {
    expect(
      filterFixtureAreaCompletions(areaCompletions, {
        facility_id: 999_999,
        date: null,
      })
    ).toEqual([]);
    expect(
      filterFixtureAreaCompletions(areaCompletions, {
        facility_id: null,
        date: "2000-01-01",
      })
    ).toEqual([]);
  });

  it("★入力の配列を壊さない（純粋関数）★", () => {
    const before = areaCompletions.length;
    filterFixtureAreaCompletions(areaCompletions, { facility_id: 999_999, date: null });
    expect(areaCompletions).toHaveLength(before);
  });
});
