/**
 * 1080P 分辨率支持 E2E — 真实浏览器验证 UI 双向约束和预估费用。
 * 针对本地开发环境（localhost:5173 + 127.0.0.1:8000）。
 */
import { test, expect, Page } from '@playwright/test';

const BASE_URL = 'http://localhost:5173';
const API_URL = 'http://127.0.0.1:8000';
const USERNAME = 'admin';
const PASSWORD = 'admin123';

async function login(page: Page) {
  const resp = await page.request.post(`${API_URL}/api/v1/auth/login`, {
    data: { username: USERNAME, password: PASSWORD },
  });
  if (!resp.ok()) {
    const err = await resp.text();
    throw new Error(`Login failed: ${resp.status()} ${err}`);
  }
  const body = await resp.json();

  await page.goto(BASE_URL);
  await page.evaluate(({ access, refresh }) => {
    localStorage.setItem('access_token', access);
    localStorage.setItem('refresh_token', refresh);
  }, { access: body.tokens.access, refresh: body.tokens.refresh });
  await page.goto(`${BASE_URL}/app`);
  await page.waitForTimeout(1500);

  // 关闭公告弹窗
  const knowBtn = page.getByRole('button', { name: /我知道了|知道了|关闭/ }).first();
  if (await knowBtn.isVisible().catch(() => false)) {
    await knowBtn.click();
    await page.waitForTimeout(300);
  }
}

test.describe.serial('1080P 分辨率支持', () => {
  test('默认分辨率显示 720P', async ({ page }) => {
    await login(page);
    // 找到 Toolbar 里的分辨率按钮（label 应显示 720P）
    const resolutionBtn = page.getByRole('button', { name: '720P', exact: true }).first();
    await expect(resolutionBtn).toBeVisible();
  });

  test('AirDrama 模式下可切换到 1080P', async ({ page }) => {
    await login(page);
    // 点分辨率按钮展开 dropdown
    await page.getByRole('button', { name: '720P', exact: true }).first().click();
    await page.waitForTimeout(200);

    // 选 1080P
    await page.getByText('1080P', { exact: true }).click();
    await page.waitForTimeout(300);

    // 分辨率按钮应显示 1080P
    await expect(page.getByRole('button', { name: '1080P', exact: true }).first()).toBeVisible();
  });

  test('1080P 下 Fast 模型置灰（UI 不可达 Fast+1080P）', async ({ page }) => {
    await login(page);
    // 先切到 1080P
    await page.getByRole('button', { name: '720P', exact: true }).first().click();
    await page.waitForTimeout(200);
    await page.getByText('1080P', { exact: true }).click();
    await page.waitForTimeout(300);

    // 打开模型 dropdown
    await page.getByRole('button', { name: /AirDrama$/, exact: false }).first().click();
    await page.waitForTimeout(200);

    // Fast 项应包含 "不支持 1080P" 且有 disabled 视觉
    const fastItem = page.getByText(/AirDrama Fast.*不支持 1080P/);
    await expect(fastItem).toBeVisible();

    // 点击 Fast 不应切换（Dropdown 的 disabled 阻止了 onSelect）
    await fastItem.click({ force: true });
    await page.waitForTimeout(300);

    // 模型应仍是 AirDrama
    await expect(page.getByRole('button', { name: /AirDrama$/, exact: false }).first()).toBeVisible();
  });

  test('Fast 模式下 1080P 置灰（UI 不可达 Fast+1080P，反向）', async ({ page }) => {
    await login(page);
    // 先确保 resolution 是 720P（reset）
    await page.reload();
    await page.waitForTimeout(1500);

    // 切到 Fast 模型
    await page.getByRole('button', { name: /AirDrama$/, exact: false }).first().click();
    await page.waitForTimeout(200);
    await page.getByText('AirDrama Fast', { exact: true }).click();
    await page.waitForTimeout(300);

    // 打开分辨率 dropdown
    await page.getByRole('button', { name: '720P', exact: true }).first().click();
    await page.waitForTimeout(200);

    // 1080P 项应带 "Fast 不支持" 标注
    const disabled1080p = page.getByText(/1080P.*Fast 不支持/);
    await expect(disabled1080p).toBeVisible();

    // 点击不生效
    await disabled1080p.click({ force: true });
    await page.waitForTimeout(300);

    // 分辨率仍为 720P（可能 Dropdown 保持打开或关闭，但按钮不该变）
    const bodyText = await page.textContent('body');
    expect(bodyText).toContain('720P');
  });

  test('预估费用 tooltip 明示「以火山为准」', async ({ page }) => {
    await login(page);
    // 需要让按钮栏里的"预估"显示出来（需要有 prompt 或素材）
    // 输入一个简单 prompt
    const promptArea = page.locator('[contenteditable]').first();
    if (await promptArea.isVisible().catch(() => false)) {
      await promptArea.click();
      await promptArea.type('测试提示词');
      await page.waitForTimeout(300);
    }

    // 找到"预估消耗"文案
    const estSpan = page.getByText(/预估消耗/).first();
    if (await estSpan.isVisible().catch(() => false)) {
      const title = await estSpan.getAttribute('title');
      expect(title).toBeTruthy();
      expect(title!).toContain('实际');
      expect(title!).toContain('火山');
    } else {
      // 如果没有预估显示（比如 team 没配单价），跳过
      console.log('跳过：预估未显示（team 可能未配单价）');
    }
  });
});
