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

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

const evidence = path.resolve(__dirname, "../../docs/evidence/stage-12");
test.beforeAll(() => fs.mkdirSync(evidence, { recursive: true }));

async function authenticate(page, username, password) {
  await page.goto("/");
  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.locator(".sidebar")).toBeVisible();
  }
}

function reviewPayload(trades = []) {
  return {
    trade_date: "2026-07-30",
    watchlist: [{ identifier: "000001.SZ", code: "000001", name: "平安银行", sector: "银行", remark: "观察承接", pct_chg: 1.28, return_5d: 3.6, attention_score: 72 }],
    daily: { id: 1, code: "", stock_name: "", trade_date: "2026-07-30", summary: "缩量分化", content: "按计划等待", plan: "观察主线承接", updated_at: "now" },
    history: [{ id: 1, code: "", stock_name: "", trade_date: "2026-07-30", summary: "缩量分化", content: "按计划等待", plan: "观察主线承接", updated_at: "now" }],
    trades,
    trade_summary: { total: trades.length, realized: trades.length, win_rate: trades.length ? 100 : null, pnl_amount: trades.length ? 120 : null, average_position: trades.length ? 20 : null },
  };
}

async function mockReview(page) {
  let trades = [];
  await page.route("**/api/review?*", (route) => route.fulfill({ contentType: "application/json", body: JSON.stringify(reviewPayload(trades)) }));
  await page.route("**/api/review/trades", async (route) => {
    const value = route.request().postDataJSON();
    trades = [{ ...value, id: 11, action_label: "买入", emotion_label: "平静" }];
    await route.fulfill({ contentType: "application/json", body: JSON.stringify({ id: 11 }) });
  });
  await page.route("**/api/review/notes", (route) => route.fulfill({ contentType: "application/json", body: JSON.stringify({ id: 1 }) }));
  await page.route("**/api/review/watchlist/**", (route) => route.fulfill({ contentType: "application/json", body: JSON.stringify({ message: "已保存" }) }));
  await page.route("**/api/review/alerts?*", (route) => route.fulfill({ contentType: "application/json", body: JSON.stringify({ items: [{ id: 1, kind: "manual", title: "复核承接", content: "开盘后观察", available_date: "2026-07-30", code: "000001", is_read: false, due: true, created_at: "now" }], unread_count: 1, as_of: "2026-07-30" }) }));
  await page.route("**/api/review/alerts", (route) => route.fulfill({ contentType: "application/json", body: JSON.stringify({ id: 2 }) }));
  await page.route("**/api/review/assistant/messages", (route) => route.fulfill({ contentType: "application/json", body: JSON.stringify(route.request().method() === "DELETE" ? { deleted: 0 } : []) }));
  await page.route("**/api/review/assistant/chat", (route) => route.fulfill({ contentType: "application/x-ndjson", body: `${JSON.stringify({ type: "delta", content: "【市场事实】温度回落。" })}\n${JSON.stringify({ type: "delta", content: "【条件化计划】等待承接确认。" })}\n${JSON.stringify({ type: "done" })}\n` }));
  await page.route("**/api/review/stock-notes/**", (route) => route.fulfill({ contentType: "application/json", body: "[]" }));
}

test("stage 12 private review, alerts and assistant remain usable", async ({ page }) => {
  const consoleErrors = [];
  page.on("console", (message) => { if (message.type() === "error" && !message.text().includes("401 (Unauthorized)")) consoleErrors.push(message.text()); });
  await mockReview(page);
  await authenticate(page, "stage4admin", "Stage4-pass-123!");
  await page.goto("/workspace/review");
  await expect(page.getByRole("heading", { name: "我的复盘" })).toBeVisible();
  await expect(page.getByText("平安银行", { exact: true })).toBeVisible();
  await expect(page.getByLabel("跟踪备注")).toHaveValue("观察承接");
  await expect(page.getByLabel("今日盘面一句话")).toHaveValue("缩量分化");
  await expect(page.getByLabel("今日做对了什么 / 做错了什么")).toHaveValue("按计划等待");
  await expect(page.getByLabel("明日策略")).toHaveValue("观察主线承接");

  await page.getByRole("button", { name: "交易日志", exact: true }).click();
  const tradeDialog = page.getByRole("dialog", { name: "交易日志" });
  await tradeDialog.getByLabel("代码").fill("000001");
  await tradeDialog.getByLabel("名称").fill("平安银行");
  await tradeDialog.getByLabel("价格（元）").fill("10.20");
  await tradeDialog.getByLabel("仓位（%）").fill("20");
  await tradeDialog.getByLabel("盈亏（%）").fill("1.2");
  await tradeDialog.getByRole("button", { name: "保存", exact: true }).click();
  await expect(tradeDialog).toHaveCount(0);
  await expect(page.getByRole("status")).toContainText("交易记录已保存");
  await expect(page.locator(".trade-scroll").getByText("平安银行", { exact: true })).toBeVisible();
  await expect(page.locator(".dialog")).toHaveCount(0);

  await page.getByRole("button", { name: "提醒中心" }).click();
  await expect(page.getByRole("dialog", { name: "提醒中心" })).toContainText("复核承接");
  await page.getByLabel("关闭").click();
  await page.getByRole("button", { name: "复盘助手" }).click();
  const assistant = page.getByRole("dialog", { name: "复盘助手" });
  await assistant.getByRole("button", { name: "市场位置" }).click();
  await assistant.getByRole("button", { name: "发送", exact: true }).click();
  await expect(assistant.getByText("【市场事实】温度回落。【条件化计划】等待承接确认。", { exact: true })).toBeVisible();
  await page.getByLabel("关闭").click();
  await page.getByRole("button", { name: "夜间" }).click();
  await page.screenshot({ path: path.join(evidence, "review-dark-1920x1080.jpg"), type: "jpeg", quality: 82 });

  await page.setViewportSize({ width: 390, height: 844 });
  expect(await page.evaluate(() => document.documentElement.scrollWidth - window.innerWidth)).toBeLessThanOrEqual(0);
  await expect(page.locator(".mobile-nav")).toBeVisible();
  await page.screenshot({ path: path.join(evidence, "review-dark-390x844.jpg"), type: "jpeg", quality: 82 });
  expect(consoleErrors).toEqual([]);
});

test("nonmembers see the complete disabled review assistant", async ({ page }) => {
  await mockReview(page);
  await authenticate(page, "stage4user", "Stage4-user-123!");
  await page.getByRole("button", { name: "复盘助手" }).click();
  const dialog = page.getByRole("dialog", { name: "复盘助手" });
  await expect(dialog.getByText("复盘助手仅对会员开放")).toBeVisible();
  await expect(dialog.getByPlaceholder(/询问市场位置/)).toBeDisabled();
  await expect(dialog.getByRole("button", { name: "市场位置" })).toBeVisible();
});
