import { describe, expect, it } from "vitest";
import { InMemoryStore } from "../../src/store.js";
import { makeClock } from "../helpers.js";

describe("subscribers/lists (TC-FR-SUB-001/002/003)", () => {
  it("作成・正規化・一覧", async () => {
    const store = new InMemoryStore(makeClock().now);
    const { subscriber, created } = await store.upsertSubscriber("  USER@Example.COM ", "太郎", "manual");
    expect(created).toBe(true);
    expect(subscriber.email).toBe("user@example.com"); // 正規化
    expect(subscriber.unsub_token).toBeTruthy();
    const list = await store.listSubscribers();
    expect(list.length).toBe(1);
  });

  it("同一emailの重複登録は新規行を作らない（冪等 TC-FR-SUB-002）", async () => {
    const store = new InMemoryStore(makeClock().now);
    await store.upsertSubscriber("a@x.com", null, "form");
    const again = await store.upsertSubscriber("A@X.com", "名前後付け", "webhook");
    expect(again.created).toBe(false);
    expect((await store.listSubscribers()).length).toBe(1);
    expect(again.subscriber.name).toBe("名前後付け"); // 空だった名前は補完
  });

  it("リスト作成・所属・解除（TC-FR-SUB-003）", async () => {
    const store = new InMemoryStore(makeClock().now);
    const list = await store.createList("読者");
    const { subscriber } = await store.upsertSubscriber("b@x.com", null, "manual");
    await store.addToList(list.id, subscriber.id);
    expect((await store.subscribersInList(list.id)).length).toBe(1);
    await store.addToList(list.id, subscriber.id); // 二重追加は無視
    expect((await store.subscribersInList(list.id)).length).toBe(1);
    await store.removeFromList(list.id, subscriber.id);
    expect((await store.subscribersInList(list.id)).length).toBe(0);
  });

  it("activeSubscribersInList は非アクティブを除外（TC-FR-BC-007）", async () => {
    const store = new InMemoryStore(makeClock().now);
    const list = await store.createList("L");
    const a = (await store.upsertSubscriber("a@x.com", null, "m")).subscriber;
    const b = (await store.upsertSubscriber("b@x.com", null, "m")).subscriber;
    await store.addToList(list.id, a.id);
    await store.addToList(list.id, b.id);
    await store.setSubscriberStatus(b.id, "unsubscribed");
    const active = await store.activeSubscribersInList(list.id);
    expect(active.map((s) => s.email)).toEqual(["a@x.com"]);
  });
});
