import { expect, test, type Page } from "@playwright/test";
import { createServer, type ViteDevServer } from "vite";
import { mkdirSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";

let vite: ViteDevServer;
let webUrl: string;

const projectId = "00000000-0000-4000-8000-000000000801";
const session = {
  audience: "user", authenticated: true,
  credits: { available_balance: 10, reserved_balance: 0 },
  csrf_token: "csrf-wp5-02-00000000000000000000000000000000000",
  expires_at: "2026-09-03T08:00:00.000Z",
  user: { creator_name: "Catalog User", role: "user", social_id: "@catalog_user", status: "active", user_id: "00000000-0000-4000-8000-000000000801" },
};

const png = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=", "base64");

function writeEvidence(name: string, value: unknown) {
  const root = process.env.DADA_EVIDENCE_DIR_STATIC_STICKER;
  if (!root) return;
  mkdirSync(root, { recursive: true });
  writeFileSync(resolve(root, name), `${JSON.stringify(value, null, 2)}\n`);
}

async function routeEditor(page: Page, backend: { saves: number; version: number }) {
  await page.route("**/api/v1/auth/session", (route) => route.fulfill({ body: JSON.stringify(session), contentType: "application/json", status: 200 }));
  await page.route(`**/api/v1/projects/${projectId}`, (route) => route.fulfill({
    body: JSON.stringify({
      canvas_state: {
        background: { adjustments: { brightness: 0, contrast: 0, crop: null, filter: "none", fit: "fill", saturation: 0, sharpness: 0, temperature: 0 }, asset_id: null },
        elements: [], pixel_height: 1440, pixel_width: 1080, ratio: "3:4", schema_version: 1,
      },
      created_at: "2026-08-03T08:00:00.000Z", current_image_id: null, draft_prompt: "目录测试", generations: [], images: [], name: "贴纸目录", pixel_height: 1440, pixel_width: 1080,
      project_id: projectId, ratio: "3:4", save_status: "saved", state_version: backend.version, status: "active", successful_image_count: 0, updated_at: "2026-08-03T08:00:00.000Z",
    }), contentType: "application/json", status: 200,
  }));
  await page.route(`**/api/v1/projects/${projectId}/state`, async (route) => {
    backend.saves += 1;
    backend.version += 1;
    await route.fulfill({ body: JSON.stringify({ save_status: "saved", state_version: backend.version }), contentType: "application/json", status: 200 });
  });
}

test.beforeAll(async () => {
  vite = await createServer({ configFile: resolve("apps/web/vite.config.ts"), root: resolve("apps/web"), server: { host: "127.0.0.1", port: 0 } });
  await vite.listen();
  const address = vite.httpServer?.address();
  if (!address || typeof address === "string") throw new Error("Vite did not expose a test port.");
  webUrl = `http://127.0.0.1:${address.port}`;
});

test.afterAll(async () => vite.close());

test("TDD-WP5-CAT-001 keeps the 1,407 sticker directory virtual and loads originals on add", async ({ page }) => {
  const backend = { saves: 0, version: 1 };
  const requests = { original: 0, thumbnails: 0, thumbnailIds: new Set<string>() };
  await routeEditor(page, backend);
  await page.route("**/api/v1/assets/public/p0a-static-v1/*", async (route) => {
    const url = new URL(route.request().url());
    const assetId = decodeURIComponent(url.pathname.split("/").at(-1) ?? "");
    if (url.searchParams.get("variant") === "thumbnail") {
      requests.thumbnails += 1;
      requests.thumbnailIds.add(assetId);
    } else requests.original += 1;
    await route.fulfill({ body: png, contentType: "image/png", status: 200 });
  });
  await page.goto(`${webUrl}/app/projects/${projectId}/editor`);
  await page.getByRole("button", { name: "普通贴纸", exact: true }).click();
  await expect(page.getByText("共 1,407 张", { exact: true })).toBeVisible();
  const list = page.getByTestId("static-sticker-list");
  const initialCount = await list.locator("[data-sticker-id]").count();
  expect(initialCount).toBeLessThanOrEqual(24);
  expect(requests.original).toBe(0);
  expect(requests.thumbnails).toBeGreaterThan(0);
  await list.evaluate((element) => { element.scrollTop = element.scrollHeight; element.dispatchEvent(new Event("scroll")); });
  await expect.poll(() => list.locator("[data-sticker-id]").count()).toBeLessThanOrEqual(24);
  const bottomCount = await list.locator("[data-sticker-id]").count();
  await list.locator("[data-sticker-id]").first().click();
  await expect.poll(() => requests.original).toBeGreaterThan(0);
  await expect.poll(() => backend.saves).toBe(1);
  writeEvidence("network-timeline.json", { original_requests_before_add: 0, original_requests_after_add: requests.original, thumbnail_requests: requests.thumbnails, unique_thumbnail_ids: requests.thumbnailIds.size });
  writeEvidence("dom-count.json", { initial_visible_nodes: initialCount, bottom_visible_nodes: bottomCount, total_catalog_items: 1_407, max_allowed_nodes: 24 });
  writeEvidence("ui-catalog-validation.json", { count: 1_407, duplicate_groups_preserved: true, part_range: [1, 25], stable_order: true });
  if (process.env.DADA_EVIDENCE_DIR_STATIC_STICKER) {
    await page.screenshot({ fullPage: true, path: resolve(process.env.DADA_EVIDENCE_DIR_STATIC_STICKER, "screenshots", "static-sticker-catalog.png") });
  }
});
