// @ts-check
const { test, expect } = require('@playwright/test');

/**
 * 移动端适配完整测试
 * 验证功能点：
 * 1. 多种设备视口适配
 * 2. 布局响应式变化
 * 3. 导航栏移动端适配
 * 4. 触摸交互测试
 * 5. 性能测试
 * 6. 截图对比
 */

// 测试设备配置
const DEVICES = [
  { name: 'iPhone SE', width: 375, height: 667 },
  { name: 'iPhone 12 Mini', width: 360, height: 780 },
  { name: 'iPhone 12', width: 390, height: 844 },
  { name: 'iPhone 14 Pro', width: 393, height: 852 },
  { name: 'iPhone 14 Pro Max', width: 430, height: 932 },
  { name: 'Samsung Galaxy S21', width: 360, height: 800 },
  { name: 'Pixel 5', width: 393, height: 851 },
  { name: 'iPad Mini', width: 768, height: 1024 },
  { name: 'iPad Air', width: 820, height: 1180 },
];

// 断点定义
const BREAKPOINTS = {
  mobile: { maxWidth: 639 },
  tablet: { minWidth: 640, maxWidth: 1023 },
  desktop: { minWidth: 1024 },
};

test.describe('移动端适配测试', () => {

  for (const device of DEVICES) {
    test.describe(`${device.name} (${device.width}x${device.height})`, () => {

      test.beforeEach(async ({ page }) => {
        await page.setViewportSize({ width: device.width, height: device.height });
        await page.goto('/?mock=true');
        await page.waitForSelector('#dc-grid > *', { timeout: 10000 });
      });

      // ==================== 基础布局测试 ====================

      test('页面无横向滚动', async ({ page }) => {
        const scrollWidth = await page.evaluate(() => document.documentElement.scrollWidth);
        const clientWidth = await page.evaluate(() => document.documentElement.clientWidth);
        expect(scrollWidth).toBeLessThanOrEqual(clientWidth + 2); // 允许 2px 误差
      });

      test('页面标题可见', async ({ page }) => {
        const title = page.locator('h1');
        await expect(title).toBeVisible();

        const box = await title.boundingBox();
        expect(box.x).toBeGreaterThanOrEqual(0);
        expect(box.x + box.width).toBeLessThanOrEqual(device.width);
      });

      test('页面内容不超出视口', async ({ page }) => {
        const body = page.locator('body');
        const box = await body.boundingBox();
        expect(box.width).toBeLessThanOrEqual(device.width + 2);
      });

      // ==================== 导航适配测试 ====================

      test('导航正确显示', async ({ page }) => {
        const isMobile = device.width < 768;

        if (isMobile) {
          // 移动端：底部导航
          await expect(page.locator('#mobile-nav')).toBeVisible();
          await expect(page.locator('#mobile-tab-monitor')).toBeVisible();
          await expect(page.locator('#mobile-tab-analytics')).toBeVisible();

          // 桌面导航应该隐藏
          await expect(page.locator('#tab-monitor')).not.toBeVisible();
          await expect(page.locator('#tab-analytics')).not.toBeVisible();
        } else {
          // 平板/桌面：顶部导航
          await expect(page.locator('#tab-monitor')).toBeVisible();
          await expect(page.locator('#tab-analytics')).toBeVisible();

          // 移动端导航应该隐藏
          await expect(page.locator('#mobile-nav')).not.toBeVisible();
        }
      });

      test('Tab 切换功能正常', async ({ page }) => {
        const isMobile = device.width < 768;

        // 切换到数据分析
        if (isMobile) {
          await page.click('#mobile-tab-analytics');
        } else {
          await page.click('#tab-analytics');
        }
        await page.waitForTimeout(500);

        await expect(page.locator('#analytics-content')).toBeVisible();
        await expect(page.locator('#data-content')).toBeHidden();

        // 切换回实时监控
        if (isMobile) {
          await page.click('#mobile-tab-monitor');
        } else {
          await page.click('#tab-monitor');
        }
        await page.waitForTimeout(500);

        await expect(page.locator('#data-content')).toBeVisible();
        await expect(page.locator('#analytics-content')).toBeHidden();
      });

      // ==================== 充电桩卡片适配测试 ====================

      test('DC 卡片正确显示', async ({ page }) => {
        const dcGrid = page.locator('#dc-grid');
        await expect(dcGrid).toBeVisible();

        const cards = dcGrid.locator('> div');
        const count = await cards.count();
        expect(count).toBeGreaterThan(0);

        // 第一张卡片应该在视口内
        const firstCard = cards.first();
        const box = await firstCard.boundingBox();
        expect(box.x).toBeGreaterThanOrEqual(0);
        expect(box.x + box.width).toBeLessThanOrEqual(device.width + 2);
      });

      test('AC 卡片正确显示', async ({ page }) => {
        const acGrid = page.locator('#ac-grid');
        await expect(acGrid).toBeVisible();

        const cards = acGrid.locator('> div');
        const count = await cards.count();
        expect(count).toBeGreaterThan(0);

        // 第一张卡片应该在视口内
        const firstCard = cards.first();
        const box = await firstCard.boundingBox();
        expect(box.x).toBeGreaterThanOrEqual(0);
        expect(box.x + box.width).toBeLessThanOrEqual(device.width + 2);
      });

      test('卡片网格响应式布局', async ({ page }) => {
        const isMobile = device.width < 768;

        // 检查 AC 卡片网格布局
        const acGrid = page.locator('#ac-grid');
        const firstCard = acGrid.locator('> div').first();
        const secondCard = acGrid.locator('> div').nth(1);

        const firstBox = await firstCard.boundingBox();
        const secondBox = await secondCard.boundingBox();

        if (device.width <= 400) {
          // 单列布局：第二张卡片应该在第一张下方
          expect(secondBox.y).toBeGreaterThan(firstBox.y + firstBox.height - 10);
        } else if (device.width < 600) {
          // 双列布局：第二张卡片可能在右侧
          expect(secondBox.x).toBeGreaterThan(firstBox.x);
        }
      });

      // ==================== 筛选器适配测试 ====================

      test('筛选器可访问', async ({ page }) => {
        const filterBar = page.locator('.filter-bar-scroll');
        await expect(filterBar).toBeVisible();

        // 所有筛选按钮应该存在
        const filters = ['filter-all', 'filter-free', 'filter-charging', 'filter-occupied'];
        for (const id of filters) {
          const btn = page.locator(`#${id}`);
          await expect(btn).toBeAttached();
        }
      });

      test('筛选功能正常', async ({ page }) => {
        // 滚动筛选器到可见区域
        await page.locator('#filter-free').scrollIntoViewIfNeeded();
        await page.click('#filter-free');
        await page.waitForTimeout(300);

        const freeBtn = page.locator('#filter-free');
        await expect(freeBtn).toHaveClass(/active/);
      });

      // ==================== 订阅栏适配测试 ====================

      test('订阅栏正确显示', async ({ page }) => {
        const isMobile = device.width < 768;

        if (isMobile) {
          // 移动端：订阅栏在底部导航上方
          const subscribeBar = page.locator('#mobile-subscribe-bar');
          await expect(subscribeBar).toBeVisible();

          const subscribeBtn = page.locator('#mobile-subscribe-btn');
          await expect(subscribeBtn).toBeVisible();
        } else {
          // 桌面端：底部悬浮订阅栏
          const bottomBar = page.locator('#bottom-bar');
          await expect(bottomBar).toBeVisible();
        }
      });

      test('订阅弹窗移动端适配', async ({ page }) => {
        const isWeekend = new Date().getDay() === 0 || new Date().getDay() === 6;
        if (isWeekend) test.skip();

        const isMobile = device.width < 768;

        // 打开订阅弹窗
        if (isMobile) {
          await page.click('#mobile-subscribe-btn');
        } else {
          await page.click('button:has-text("订阅提醒")');
        }

        await expect(page.locator('#subscribe-modal')).toBeVisible();

        // 弹窗内容应该在视口内
        const modal = page.locator('.modal-content');
        const box = await modal.boundingBox();
        expect(box.x).toBeGreaterThanOrEqual(0);
        expect(box.x + box.width).toBeLessThanOrEqual(device.width + 2);

        // 输入框应该可见且可交互
        await expect(page.locator('#feishu-name-input')).toBeVisible();
        await expect(page.locator('#email-input')).toBeVisible();
      });

      // ==================== 数据分析页面适配测试 ====================

      test('数据分析页面可滚动查看', async ({ page }) => {
        const isMobile = device.width < 768;

        // 切换到数据分析
        if (isMobile) {
          await page.click('#mobile-tab-analytics');
        } else {
          await page.click('#tab-analytics');
        }
        await page.waitForTimeout(1500);

        // 数据概览应该可见
        await expect(page.locator('#overview-cards')).toBeVisible();

        // 排名图表存在即可
        await expect(page.locator('#rank-chart')).toBeAttached();
      });

      test('数据分析页面无横向滚动', async ({ page }) => {
        const isMobile = device.width < 768;

        if (isMobile) {
          await page.click('#mobile-tab-analytics');
        } else {
          await page.click('#tab-analytics');
        }
        await page.waitForTimeout(1000);

        const scrollWidth = await page.evaluate(() => document.documentElement.scrollWidth);
        const clientWidth = await page.evaluate(() => document.documentElement.clientWidth);
        expect(scrollWidth).toBeLessThanOrEqual(clientWidth + 2);
      });

      // ==================== 触摸交互测试 ====================

      test('触摸滑动筛选器', async ({ page }) => {
        const filterBar = page.locator('.filter-bar-scroll');
        const box = await filterBar.boundingBox();

        // 模拟触摸滑动
        await page.mouse.move(box.x + box.width - 10, box.y + box.height / 2);
        await page.mouse.down();
        await page.mouse.move(box.x + 10, box.y + box.height / 2, { steps: 10 });
        await page.mouse.up();

        // 筛选器应该仍然可见
        await expect(filterBar).toBeVisible();
      });

      test('触摸滚动页面', async ({ page }) => {
        // 获取页面高度
        const bodyHeight = await page.evaluate(() => document.body.scrollHeight);
        const viewportHeight = device.height;

        if (bodyHeight > viewportHeight) {
          // 滚动到页面底部
          await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
          await page.waitForTimeout(300);

          // 滚动回顶部
          await page.evaluate(() => window.scrollTo(0, 0));
          await page.waitForTimeout(300);

          // 页面应该正常显示
          await expect(page.locator('h1')).toBeVisible();
        }
      });

      // ==================== 刷新功能测试 ====================

      test('刷新按钮可点击', async ({ page }) => {
        const refreshBtn = page.locator('button[title="手动刷新"]');
        await expect(refreshBtn).toBeVisible();

        // 使用 force 点击绕过 Mock 设置按钮遮挡
        await refreshBtn.click({ force: true });

        // 刷新后页面应该正常
        await expect(page.locator('#dc-grid > div').first()).toBeVisible();
      });
    });
  }
});

// ==================== 安全区域适配测试（iPhone X 等） ====================

test.describe('安全区域适配（iPhone X）', () => {

  test('iPhone X 底部安全区域', async ({ page }) => {
    await page.setViewportSize({ width: 375, height: 812 });
    await page.goto('/?mock=true');
    await page.waitForSelector('#dc-grid > *', { timeout: 10000 });

    // 检查底部导航栏存在
    const mobileNav = page.locator('#mobile-nav');
    await expect(mobileNav).toBeVisible();

    // 导航栏应该在视口底部
    const navBox = await mobileNav.boundingBox();
    expect(navBox.y + navBox.height).toBeGreaterThan(800);
  });

  test('订阅栏在安全区域上方', async ({ page }) => {
    await page.setViewportSize({ width: 375, height: 812 });
    await page.goto('/?mock=true');
    await page.waitForSelector('#dc-grid > *', { timeout: 10000 });

    // 订阅栏应该在底部导航上方
    const subscribeBar = page.locator('#mobile-subscribe-bar');
    const mobileNav = page.locator('#mobile-nav');

    await expect(subscribeBar).toBeVisible();
    await expect(mobileNav).toBeVisible();

    const subscribeBox = await subscribeBar.boundingBox();
    const navBox = await mobileNav.boundingBox();

    // 订阅栏底部应该在导航栏顶部附近（允许一定误差）
    expect(subscribeBox.y + subscribeBox.height).toBeLessThanOrEqual(navBox.y + 20);
  });
});

// ==================== 横屏适配测试 ====================

test.describe('横屏适配测试', () => {

  test('iPhone 横屏布局', async ({ page }) => {
    await page.setViewportSize({ width: 844, height: 390 });
    await page.goto('/?mock=true');
    await page.waitForSelector('#dc-grid > *', { timeout: 10000 });

    // 页面应该无横向滚动
    const scrollWidth = await page.evaluate(() => document.documentElement.scrollWidth);
    const clientWidth = await page.evaluate(() => document.documentElement.clientWidth);
    expect(scrollWidth).toBeLessThanOrEqual(clientWidth + 2);

    // 内容应该正常显示
    await expect(page.locator('#dc-grid > div').first()).toBeVisible();
    await expect(page.locator('#ac-grid > div').first()).toBeVisible();
  });

  test('iPad 横屏布局', async ({ page }) => {
    await page.setViewportSize({ width: 1024, height: 768 });
    await page.goto('/?mock=true');
    await page.waitForSelector('#dc-grid > *', { timeout: 10000 });

    // 平板应该显示桌面导航
    await expect(page.locator('#tab-monitor')).toBeVisible();
    await expect(page.locator('#tab-analytics')).toBeVisible();

    // 移动端导航应该隐藏
    await expect(page.locator('#mobile-nav')).not.toBeVisible();
  });
});

// ==================== 字体和可读性测试 ====================

test.describe('字体和可读性测试', () => {

  test('移动端字体大小适中', async ({ page }) => {
    await page.setViewportSize({ width: 375, height: 667 });
    await page.goto('/?mock=true');
    await page.waitForSelector('#dc-grid > *', { timeout: 10000 });

    // 检查标题字体大小
    const title = page.locator('h1');
    const fontSize = await title.evaluate(el => window.getComputedStyle(el).fontSize);
    const size = parseFloat(fontSize);
    expect(size).toBeGreaterThanOrEqual(14); // 至少 14px
  });

  test('卡片内容可读', async ({ page }) => {
    await page.setViewportSize({ width: 375, height: 667 });
    await page.goto('/?mock=true');
    await page.waitForSelector('#dc-grid > *', { timeout: 10000 });

    // 检查卡片内容
    const firstCard = page.locator('#ac-grid > div').first();
    const text = await firstCard.innerText();
    expect(text.length).toBeGreaterThan(0);
  });
});

// ==================== 性能测试 ====================

test.describe('移动端性能测试', () => {

  test('页面加载时间', async ({ page }) => {
    await page.setViewportSize({ width: 375, height: 667 });

    const startTime = Date.now();
    await page.goto('/?mock=true');
    await page.waitForSelector('#dc-grid > *', { timeout: 10000 });
    const loadTime = Date.now() - startTime;

    // 页面加载时间应该小于 5 秒
    expect(loadTime).toBeLessThan(5000);
  });

  test('筛选响应时间', async ({ page }) => {
    await page.setViewportSize({ width: 375, height: 667 });
    await page.goto('/?mock=true');
    await page.waitForSelector('#dc-grid > *', { timeout: 10000 });

    const startTime = Date.now();
    await page.click('#filter-free');
    await page.waitForTimeout(100);
    const responseTime = Date.now() - startTime;

    // 筛选响应时间应该小于 500ms
    expect(responseTime).toBeLessThan(500);
  });
});

// ==================== 截图对比 ====================

test.describe('移动端截图', () => {

  test('iPhone SE 首页截图', async ({ page }) => {
    await page.setViewportSize({ width: 375, height: 667 });
    await page.goto('/?mock=true');
    await page.waitForSelector('#dc-grid > *', { timeout: 10000 });
    await page.waitForTimeout(500);

    await page.screenshot({
      path: 'test-results/mobile-iphone-se-home.png',
      fullPage: true
    });
  });

  test('iPhone 12 首页截图', async ({ page }) => {
    await page.setViewportSize({ width: 390, height: 844 });
    await page.goto('/?mock=true');
    await page.waitForSelector('#dc-grid > *', { timeout: 10000 });
    await page.waitForTimeout(500);

    await page.screenshot({
      path: 'test-results/mobile-iphone-12-home.png',
      fullPage: true
    });
  });

  test('iPad Mini 首页截图', async ({ page }) => {
    await page.setViewportSize({ width: 768, height: 1024 });
    await page.goto('/?mock=true');
    await page.waitForSelector('#dc-grid > *', { timeout: 10000 });
    await page.waitForTimeout(500);

    await page.screenshot({
      path: 'test-results/mobile-ipad-mini-home.png',
      fullPage: true
    });
  });

  test('iPhone 数据分析页面截图', async ({ page }) => {
    await page.setViewportSize({ width: 375, height: 667 });
    await page.goto('/?mock=true');
    await page.waitForSelector('#dc-grid > *', { timeout: 10000 });

    await page.click('#mobile-tab-analytics');
    await page.waitForTimeout(1500);

    await page.screenshot({
      path: 'test-results/mobile-iphone-se-analytics.png',
      fullPage: true
    });
  });

  test('订阅弹窗截图', async ({ page }) => {
    const isWeekend = new Date().getDay() === 0 || new Date().getDay() === 6;
    if (isWeekend) test.skip();

    await page.setViewportSize({ width: 375, height: 667 });
    await page.goto('/?mock=true');
    await page.waitForSelector('#dc-grid > *', { timeout: 10000 });

    await page.click('#mobile-subscribe-btn');
    await page.waitForTimeout(300);

    await page.screenshot({
      path: 'test-results/mobile-iphone-se-subscribe-modal.png'
    });
  });
});
