const fs = require("node:fs");
const path = require("node:path");

const { expect, test } = require("@playwright/test");

const evidence = path.resolve(__dirname, "../../docs/evidence/stage-4");

test.beforeAll(() => fs.mkdirSync(evidence, { recursive: true }));

async function authenticate(page, username, password) {
  await page.goto("/");
  await expect(page.getByRole("heading", { name: "小白复盘" })).toBeVisible();
  await page.getByLabel("账号名").fill(username);
  await page.getByLabel("密码").fill(password);
  await page.getByRole("button", { name: "登录", exact: true }).click();
  await expect(page.locator(".sidebar, .field-error")).toBeVisible();
  if (!(await page.locator(".sidebar").isVisible())) {
    await page.getByRole("tab", { name: "注册" }).click();
    await page.getByRole("button", { name: "注册并登录" }).click();
  }
  await expect(page.getByRole("navigation", { name: "主导航", exact: true })).toBeVisible();
}

test("authentication, shell, dialogs, theme and responsive structure", async ({ page }) => {
  const consoleErrors = [];
  const unexpectedResponses = [];
  page.on("console", (message) => {
    if (message.type() === "error" && !message.text().includes("401 (Unauthorized)")) {
      consoleErrors.push(message.text());
    }
  });
  page.on("response", (response) => {
    const expectedAnonymousProbe = response.status() === 401 && response.url().endsWith("/api/auth/session");
    if (response.status() >= 400 && !expectedAnonymousProbe) {
      unexpectedResponses.push(`${response.status()} ${response.url()}`);
    }
  });

  await authenticate(page, "stage4admin", "Stage4-pass-123!");
  await expect(page.getByText("管理员", { exact: true })).toBeVisible();
  await expect(page.getByRole("button", { name: "系统管理" })).toBeVisible();
  await expect(page.locator(".nav-item")).toHaveCount(16);

  await page.getByRole("button", { name: /stage4admin/ }).click();
  const accountMenu = page.locator(".account-menu");
  await expect(accountMenu.getByRole("button")).toHaveCount(5);
  await accountMenu.getByRole("button", { name: "个人资料" }).click();
  const profileDialog = page.getByRole("dialog", { name: "个人资料" });
  await expect(profileDialog).toBeVisible();
  await profileDialog.getByLabel("出生日期").fill("1990-03-08");
  await profileDialog.getByLabel("出生时间").fill("08:30");
  await profileDialog.getByLabel("性别").selectOption("male");
  await profileDialog.getByRole("button", { name: "保存", exact: true }).click();
  await expect(page.getByRole("status")).toContainText("个人资料已保存");
  await page.getByLabel("关闭").click();

  await page.getByRole("button", { name: "普通用户" }).click();
  await expect(page.getByRole("dialog", { name: "会员状态" })).toContainText("智能选股、问师、问天、复盘助手");
  await page.getByLabel("关闭").click();

  await page.getByRole("button", { name: /stage4admin/ }).click();
  await page.locator(".account-menu").getByRole("button", { name: "修改密码" }).click();
  const passwordDialog = page.getByRole("dialog", { name: "修改密码" });
  await expect(passwordDialog.getByLabel("当前密码")).toBeVisible();
  await expect(passwordDialog.getByLabel("确认新密码")).toBeVisible();
  await page.getByLabel("关闭").click();

  await page.keyboard.press("Control+K");
  const searchDialog = page.getByRole("dialog", { name: "全局搜索" });
  await expect(searchDialog).toBeVisible();
  const dialogBox = await searchDialog.boundingBox();
  expect(dialogBox).not.toBeNull();
  expect(Math.abs(dialogBox.x + dialogBox.width / 2 - 960)).toBeLessThan(2);
  await page.keyboard.press("Escape");

  const desktopMetrics = await page.evaluate(() => ({
    topbar: document.querySelector(".topbar")?.getBoundingClientRect().height,
    sidebar: document.querySelector(".sidebar")?.getBoundingClientRect().width,
    paddingTop: getComputedStyle(document.querySelector(".page-frame")).paddingTop,
    paddingLeft: getComputedStyle(document.querySelector(".page-frame")).paddingLeft,
    overflow: document.documentElement.scrollWidth - window.innerWidth,
  }));
  expect(desktopMetrics).toEqual({ topbar: 46, sidebar: 200, paddingTop: "14px", paddingLeft: "16px", overflow: 0 });
  await page.screenshot({ path: path.join(evidence, "shell-light-1920x1080.jpg"), type: "jpeg", quality: 82 });

  await page.getByRole("button", { name: "夜间" }).click();
  await expect(page.locator("html")).toHaveAttribute("data-theme", "dark");
  const switchedSurfaces = await page.evaluate(() => {
    const selectors = ["html", "body", ".sidebar", ".topbar", ".market-strip", ".card"];
    return selectors.map((selector) => {
      const element = document.querySelector(selector);
      return { selector, background: element ? getComputedStyle(element).backgroundColor : null };
    });
  });
  expect(switchedSurfaces.every(({ background }) => background && background !== "rgb(255, 255, 255)")).toBe(true);
  await page.reload();
  await expect(page.locator("html")).toHaveAttribute("data-theme", "dark");
  expect(await page.evaluate(() => ({
    theme: document.documentElement.dataset.theme,
    canvas: getComputedStyle(document.documentElement).backgroundColor,
    body: getComputedStyle(document.body).backgroundColor,
  }))).toEqual({ theme: "dark", canvas: "rgb(18, 20, 22)", body: "rgb(18, 20, 22)" });
  await expect(page.getByRole("button", { name: "日间" })).toBeVisible();
  await page.screenshot({ path: path.join(evidence, "shell-dark-1920x1080.jpg"), type: "jpeg", quality: 82 });

  await page.getByRole("button", { name: "系统管理" }).click();
  await expect(page.getByRole("heading", { name: "系统管理" })).toBeVisible();
  await expect(page.getByRole("tab")).toHaveCount(0);
  await expect(page.getByRole("button", { name: "行情管理" })).toBeVisible();
  await expect(page.getByRole("button", { name: "模型池" })).toBeVisible();
  await expect(page.getByRole("button", { name: "会员管理" })).toBeVisible();
  await page.getByRole("button", { name: "模型池" }).click();
  await expect(page.getByRole("heading", { name: "添加模型" })).toBeVisible();
  await page.getByRole("button", { name: "会员管理" }).click();
  await expect(page.getByRole("heading", { name: "账号会员状态" })).toBeVisible();
  await page.getByRole("button", { name: "行情管理" }).click();

  await page.setViewportSize({ width: 3840, height: 2160 });
  expect(await page.evaluate(() => document.documentElement.scrollWidth - window.innerWidth)).toBe(0);
  await page.screenshot({ path: path.join(evidence, "system-dark-3840x2160.jpg"), type: "jpeg", quality: 72 });

  await page.goto("/workspace/emotion");
  await page.setViewportSize({ width: 390, height: 844 });
  await expect(page.getByRole("navigation", { name: "移动端主导航" })).toBeVisible();
  await expect(page.getByRole("navigation", { name: "主导航", exact: true })).toBeHidden();
  expect(await page.evaluate(() => document.documentElement.scrollWidth - window.innerWidth)).toBe(0);
  await page.screenshot({ path: path.join(evidence, "shell-dark-390x844.jpg"), type: "jpeg", quality: 82 });

  expect(consoleErrors).toEqual([]);
  expect(unexpectedResponses).toEqual([]);
});

test("regular users do not receive administrator controls and see intelligent locks", async ({ page }) => {
  await authenticate(page, "stage4user", "Stage4-user-123!");
  await expect(page.getByText("管理员", { exact: true })).toHaveCount(0);
  await expect(page.getByRole("button", { name: "系统管理" })).toHaveCount(0);
  await expect(page.getByRole("button", { name: "后台刷新" })).toHaveCount(0);

  await page.goto("/system");
  await expect(page).toHaveURL(/\/workspace\/emotion$/);

  await page.goto("/workspace/screener");
  await expect(page.getByText("智能选股仅对会员开放")).toBeVisible();
  await expect(page.getByRole("button", { name: "查看会员状态" })).toBeVisible();
});

test("empty bootstrap, latest default and background refresh preserve the current workspace", async ({ page }) => {
  let synchronized = false;
  await page.route("**/api/market/summary", (route) => route.fulfill({
    contentType: "application/json",
    body: JSON.stringify(synchronized
      ? {
          context: {
            requested_date: "2026-07-30", actual_date: "2026-07-29", previous_date: "2026-07-28",
            observed_at: "2026-07-29T15:00:00+08:00", state: "final", carried_forward: true,
            message: "沿用最近真实收盘快照",
          },
          values: { temperature: 42, limit_up: 68, limit_down: 4, broken: 24, seal_rate: 73.9, amount: 1628000000000 },
        }
      : {
          context: {
            requested_date: "2026-07-30", actual_date: null, previous_date: null,
            observed_at: null, state: null, carried_forward: false, message: "等待管理员首次同步",
          },
          values: null,
        }),
  }));
  await page.route("**/api/market/workspaces/emotion?*", (route) => route.fulfill({
    contentType: "application/json",
    body: JSON.stringify(synchronized
      ? {
          trade_date: "2026-07-29", observed_at: "2026-07-29T15:00:00+08:00", carried_forward: true,
          message: "沿用最近真实收盘快照", overview: { limit_up: 68, limit_down: 4, broken: 24, seal_rate: 73.9, amount: 1628000000000 },
          sentiment: { score: 42, phase: "退潮", direction: "降温", confidence: 92, stats: {}, components: [] }, history: [],
        }
      : { trade_date: null, carried_forward: false, message: "等待管理员首次同步真实收盘行情", overview: {} }),
  }));
  await page.route("**/api/market/snapshot-sync?*", (route) => {
    synchronized = true;
    return route.fulfill({ contentType: "application/json", body: JSON.stringify({ trade_date: "2026-07-29", temperature: 42 }) });
  });

  await authenticate(page, "stage4admin", "Stage4-pass-123!");
  await expect(page).toHaveURL(/\/workspace\/emotion$/);
  await expect(page.getByText("等待管理员首次同步真实收盘行情")).toBeVisible();
  await expect(page.locator(".market-strip-row")).not.toContainText(/涨停\s+\d/);

  await page.locator(".page-frame").evaluate((element) => { element.dataset.acceptanceMarker = "preserved"; });
  await page.getByRole("button", { name: "后台刷新" }).click();
  await expect(page.getByRole("status")).toContainText("刷新页面后读取新数据");
  await expect(page).toHaveURL(/\/workspace\/emotion$/);
  await expect(page.locator('[data-acceptance-marker="preserved"]')).toBeVisible();
  await expect(page.getByText("等待管理员首次同步真实收盘行情")).toBeVisible();

  await page.reload();
  await expect(page.getByRole("heading", { name: "情绪周期" })).toBeVisible();
  await expect(page.locator(".topbar .date-input")).toHaveValue("2026-07-29");
  await expect(page.locator(".market-strip-row")).toContainText("涨停 68");
});
