import { describe, expect, it } from "vitest";

import { cleanAreaVisibility } from "@/lib/clean-area/visibility";
import { CLEAN_AREA_INITIAL_VISIBLE } from "@/lib/config";

/**
 * 指示書AN §5-3 C群（C-3 / C-4）。
 *
 * | # | 入力 | 期待 |
 * |---|---|---|
 * | C-3 | 11件・初期表示10件 | ★10件＋「もっと表示（あと1件）」★ |
 * | C-4 | ★ちょうど10件★ | ★★「もっと表示」を出さない★★ |
 *
 * ★C-3 と C-4 の両方を入れてある★ — `>` と `>=` の取り違えが通らないようにするため
 *   （ちょうど10件で「もっと表示」が出ると、押しても1件も増えない）。
 *
 * ★件数を直書きしない★（`CLAUDE.md` §7）— `CLEAN_AREA_INITIAL_VISIBLE` から作るので、
 *   設定値を変えてもこの表の意味は変わらない。
 */

/** n 件ぶんのダミー行（`cleanAreaVisibility()` は中身を見ないので数値で足りる） */
function items(n: number): number[] {
  return Array.from({ length: n }, (_, i) => i + 1);
}

const N = CLEAN_AREA_INITIAL_VISIBLE;

describe("cleanAreaVisibility", () => {
  it("0件: 0行・ボタンを出さない", () => {
    const v = cleanAreaVisibility(items(0), false);

    expect(v.visible).toEqual([]);
    expect(v.remaining).toBe(0);
    expect(v.canToggle).toBe(false);
  });

  it("初期表示件数より少なければ全部出し、ボタンを出さない", () => {
    const v = cleanAreaVisibility(items(N - 3), false);

    expect(v.visible).toHaveLength(N - 3);
    expect(v.remaining).toBe(0);
    expect(v.canToggle).toBe(false);
  });

  it("C-4 ★ちょうど初期表示件数のときはボタンを出さない★（押しても増えないため）", () => {
    const v = cleanAreaVisibility(items(N), false);

    expect(v.visible).toHaveLength(N);
    expect(v.remaining).toBe(0);
    expect(v.canToggle).toBe(false);
  });

  it("C-3 ★1件超えたら初期表示件数だけ出し、「あと1件」のボタンを出す★", () => {
    const v = cleanAreaVisibility(items(N + 1), false);

    expect(v.visible).toHaveLength(N);
    expect(v.visible).toEqual(items(N));
    expect(v.remaining).toBe(1);
    expect(v.canToggle).toBe(true);
  });

  it("開いたら全件出て、ボタンは残る（＝「閉じる」に切り替わる）", () => {
    const v = cleanAreaVisibility(items(N + 1), true);

    expect(v.visible).toHaveLength(N + 1);
    expect(v.remaining).toBe(0);
    expect(v.canToggle).toBe(true);
  });

  it("★並び順を変えない★（先頭から順に切るだけ）", () => {
    const v = cleanAreaVisibility(["a", "b", "c"], false);

    expect(v.visible).toEqual(["a", "b", "c"]);
  });

  it("★切るのは表示だけ（総数は呼び出し側の items.length）★", () => {
    const v = cleanAreaVisibility(items(N + 25), false);

    expect(v.visible).toHaveLength(N);
    expect(v.remaining).toBe(25);
    expect(v.canToggle).toBe(true);
  });
});
