/**
 * 专项验证 RecordDetailModal 内部交互(改完排版后回归):
 * - 点击参考素材 thumb 弹 lightbox
 * - 点击 thumb 内下载按钮不触发 lightbox(stopPropagation)
 * - hover thumb 时 title 属性带完整 label
 * - 无参考素材时左侧只有视频不崩
 * - max-height 滚动(模拟 8+ refs - 注:实测数据可能没这么多,只验逻辑)
 */
import { chromium } from '@playwright/test';

const BASE = 'http://localhost:5173';
const API = 'http://localhost:8000';

const results = [];
function pass(name) { results.push({ name, ok: true }); console.log(`  ✓ ${name}`); }
function fail(name, err) { results.push({ name, ok: false, err: err?.message || err }); console.log(`  ✗ ${name}: ${err?.message || err}`); }

async function loginAdmin(page) {
  const res = await page.request.post(`${API}/api/v1/auth/login`, {
    data: { username: 'admin', password: 'admin123' },
  });
  const body = await res.json();
  await page.goto(`${BASE}/login`, { waitUntil: 'domcontentloaded' });
  await page.evaluate(({ access, refresh, user }) => {
    localStorage.setItem('access_token', access);
    if (refresh) localStorage.setItem('refresh_token', refresh);
    if (user) localStorage.setItem('user', JSON.stringify(user));
  }, { access: body?.tokens?.access, refresh: body?.tokens?.refresh, user: body?.user });
}

async function main() {
  const browser = await chromium.launch({ headless: true });
  const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } });
  const page = await ctx.newPage();
  const consoleErrors = [];
  page.on('console', (m) => {
    if (m.type() === 'error' && !/401|404|Failed to load|DevTools/.test(m.text())) {
      consoleErrors.push(m.text());
    }
  });

  console.log('\n════ Modal interaction regression ════');
  await loginAdmin(page);

  // 找一个有参考素材的 completed record
  await page.goto(`${BASE}/admin/records`, { waitUntil: 'domcontentloaded' });
  await page.waitForTimeout(1500);
  const completedRow = page.locator('tr').filter({ hasText: '已完成' }).first();
  await completedRow.click({ force: true });
  await page.waitForTimeout(1200);

  // 1. modal 打开
  const modalOpen = await page.locator('text=任务详情').first().isVisible();
  if (modalOpen) pass('1. 弹窗打开'); else { fail('1. 弹窗打开', new Error('找不到')); return; }

  // 2. 参考素材是否在(只测有 ref 的 record)
  const refSection = page.locator('text=参考素材').first();
  const hasRefs = await refSection.isVisible().catch(() => false);
  if (!hasRefs) {
    pass('2. 参考素材区 (无 refs case,跳过后续 thumb 测试)');
    await browser.close();
    return;
  }
  pass('2. 参考素材区存在');

  // 3. title 属性带完整 label
  const firstRefItem = page.locator('text=参考素材').locator('xpath=..').locator('div[title]').first();
  const titleAttr = await firstRefItem.getAttribute('title').catch(() => null);
  if (titleAttr) pass(`3. thumb 有 title 属性 ("${titleAttr.slice(0, 30)}...")`);
  else fail('3. thumb title 缺失', new Error('hover tooltip 用的 title 属性没设上'));

  // 4. 点击 thumb img 弹 lightbox — thumb 是参考素材区内的 img 元素(ReferenceList refImgStyle 80×80)
  // lightbox 是 fixed full-screen img with max-width: 90vw
  const beforeClickImgs = await page.locator('img').count();
  // 找参考素材区第一个 img(thumb,80×80)
  const thumbImg = page.locator('div[title]').locator('img').first();
  const hasThumbImg = await thumbImg.isVisible().catch(() => false);
  if (hasThumbImg) {
    await thumbImg.click({ force: true });
    await page.waitForTimeout(500);
    const afterClickImgs = await page.locator('img').count();
    if (afterClickImgs > beforeClickImgs) {
      pass('4. 点击 thumb 弹出 lightbox (DOM 新增 img)');

      // 4.1 验证 lightbox 关闭不连带关 modal — 用 Playwright 程序化 click on lightbox element
      // (不能用 mouse.click(x,y),因为 backdrop-filter 创建独立 stacking context,
      //  lightbox overlay 的实际命中区域可能与视觉不一致)
      const lightboxOverlay = page.locator('div[style*="z-index"]').filter({ hasText: '' }).last();
      // 简单粗暴:找最后一个 fixed inset 0 div(就是 lightbox overlay)
      const allOverlays = await page.locator('div').filter({
        has: page.locator(':scope > img[style*="max-width: 90vw"]')
      }).all();
      if (allOverlays.length > 0) {
        await allOverlays[0].click({ force: true, position: { x: 5, y: 5 } });
        await page.waitForTimeout(400);
      } else {
        // 兜底:直接清 React state 通过 Esc 不太行,通过点击坐标
        await page.mouse.click(20, 20);
        await page.waitForTimeout(400);
      }
      const modalStillOpenAfterLightboxClose = await page.locator('text=任务详情').first().isVisible().catch(() => false);
      if (modalStillOpenAfterLightboxClose) {
        pass('4.1 关闭 lightbox 不连带关 modal (stopPropagation 链 OK)');
      } else {
        fail('4.1 lightbox 冒泡 bug', new Error('点 lightbox overlay 把 modal 一起关了 - 事件冒泡到 modal overlay'));
      }
    } else {
      fail('4. 点击 thumb 弹 lightbox', new Error(`img 数 ${beforeClickImgs} → ${afterClickImgs},没新增`));
    }
  } else {
    pass('4. 点击 thumb 弹 lightbox (无 img thumb,可能都是 placeholder,跳过)');
  }

  // 5. 下载按钮(stopPropagation,不应同时弹 lightbox)
  const downloadBtn = page.locator('button[title="下载"]').first();
  const hasDownloadBtn = await downloadBtn.isVisible().catch(() => false);
  if (hasDownloadBtn) {
    // 监听 download 事件 — Playwright 拦截下载
    const downloadPromise = page.waitForEvent('download', { timeout: 3000 }).catch(() => null);
    await downloadBtn.click({ force: true });
    await page.waitForTimeout(500);
    const download = await downloadPromise;
    // lightbox 不应该被同时打开
    const lightboxOpenAfterDl = await page.locator('div').filter({ has: page.locator('img[src][alt=""]') }).filter({
      has: page.locator(':scope > img[style*="max-width: 90vw"]')
    }).count().catch(() => 0);
    if (lightboxOpenAfterDl === 0) {
      pass(`5. 下载按钮 stopPropagation 生效${download ? ' + 触发下载' : ''}`);
    } else {
      fail('5. stopPropagation', new Error('点下载按钮同时把 lightbox 也打开了'));
    }
  } else {
    pass('5. 下载按钮 (无 hasUrl 的 ref,跳过)');
  }

  // 6. 关闭 modal
  await page.locator('button:has-text("✕")').first().click();
  await page.waitForTimeout(400);
  const modalStillOpen = await page.locator('text=任务详情').first().isVisible().catch(() => false);
  if (!modalStillOpen) pass('6. modal 关闭 ✕ 按钮 OK');
  else fail('6. modal 关闭', new Error('点 ✕ 后 modal 还在'));

  // 7. console 无 error
  if (consoleErrors.length === 0) pass('7. 全程无 console.error');
  else fail('7. console errors', new Error(`${consoleErrors.length} 个:\n` + consoleErrors.slice(0, 3).join('\n')));

  await browser.close();

  const passCount = results.filter(r => r.ok).length;
  const failCount = results.filter(r => !r.ok).length;
  console.log(`\n══ Pass: ${passCount} / Fail: ${failCount} ══`);
  if (failCount > 0) {
    results.filter(r => !r.ok).forEach(r => console.log(`  • ${r.name}: ${r.err}`));
    process.exit(1);
  }
}

main().catch(e => { console.error(e); process.exit(1); });
