import { describe, expect, it } from "vitest";

import { db } from "@/lib/db";
import { cleanLogs, unscheduledCleanLogs } from "@/lib/fixtures";
import type { CleanLogDbQuery } from "@/lib/types";

/**
 * fixtures 版 `cleanLogRunMeta()`（指示書AV 段階3-2 / 3-3）。
 *
 * ★fixtures には予定の終了も清掃エリアも無い★（指示書AV §2 D10）ので、
 *   ★終了＝開始（`scheduled_at`）★・★清掃エリア＝ロボット（`serial_number`）★とみなす。
 * ★★`cleanLogs()` と同じ `filterFixtureCleanLogs()` を通す★★ので、
 *   `facility_ids` の `null`（絞らない）/ `[]`（0件）の扱いが `cleanLogs()` と同じになる（罠1）。
 *
 * ★`USE_FIXTURES` は既定（未設定＝true）のまま★ — `db` は fixtures 版。
 */

const ALL: CleanLogDbQuery = { id: null, date_from: null, date_to: null, facility_ids: null };

describe("fixtures 版 cleanLogRunMeta()（指示書AV 段階3-2）", () => {
  it("`facility_ids: null` で全件（`cleanLogs()` と同じ id の並び）", async () => {
    const meta = await db.cleanLogRunMeta(ALL);
    const logs = await db.cleanLogs(ALL);
    // ★予定外タスクの行（`id: null`。指示書BG §2-1）もメタを持つ★（指示書BG §2-2。直近の候補にするため）—
    //   ★鍵は `row_key`★。`cleanLogs()` と同じ行の集合（並びは `cleanLogs()` が並べ直すので集合で比べる）
    expect(meta).toHaveLength(cleanLogs.length + unscheduledCleanLogs.length);
    expect(meta.map((m) => m.row_key).sort()).toEqual(logs.map((r) => r.row_key).sort());
  });

  it("`facility_ids: []` で `[]`（★0件ヒット。全件に化けない★）", async () => {
    expect(await db.cleanLogRunMeta({ ...ALL, facility_ids: [] })).toEqual([]);
  });

  it("★終了＝開始★・★清掃エリア＝ロボット★（D10）", async () => {
    const meta = await db.cleanLogRunMeta(ALL);
    const byKey = new Map([...cleanLogs, ...unscheduledCleanLogs].map((r) => [r.row_key, r]));
    for (const m of meta) {
      const row = byKey.get(m.row_key);
      expect(row).toBeDefined();
      expect(m.planned_end_at).toBe(row?.scheduled_at);
      expect(m.section_key).toBe(`fixture-robot:${row?.serial_number}`);
    }
  });

  it("同じ条件なら `cleanLogs()` と同じ行の集合になる（施設・日付で絞ったとき）", async () => {
    const day = cleanLogs[0].scheduled_at.slice(0, 10);
    const facilityId = cleanLogs[0].facility_id;
    const query: CleanLogDbQuery = {
      id: null,
      date_from: day,
      date_to: day,
      facility_ids: [facilityId],
    };
    const meta = await db.cleanLogRunMeta(query);
    const logs = await db.cleanLogs(query);
    expect(meta.length).toBeGreaterThan(0);
    expect(meta.map((m) => m.row_key).sort()).toEqual(logs.map((r) => r.row_key).sort());
  });
});
