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

const APP_TITLE = '巨人内部充电桩';
const DC_CARD_SELECTOR = '#dc-grid > [data-connector-id]';
const AC_CARD_SELECTOR = '#ac-grid > [data-connector-id]';

async function waitForCards(page) {
  await page.waitForSelector(DC_CARD_SELECTOR, { timeout: 10000 });
  await page.waitForSelector(AC_CARD_SELECTOR, { timeout: 10000 });
}

test.describe('充电桩监控系统', () => {

  test.beforeEach(async ({ page }) => {
    await page.addInitScript(() => {
      sessionStorage.setItem('dc_intro_played', '1');
      localStorage.setItem('guide_dismissed_until', String(Date.now() + 30 * 24 * 60 * 60 * 1000));
    });
  });

  test.describe('Header 导航', () => {

    test('导航 Tab 在 Header 中居中显示', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

      // 获取导航 Tab 容器
      const navContainer = page.locator('#tab-monitor').locator('..');
      const header = page.locator('header');

      const headerBox = await header.boundingBox();
      const navBox = await navContainer.boundingBox();

      // 导航应在 header 水平居中（允许 10px 误差）
      const navCenter = navBox.x + navBox.width / 2;
      const headerCenter = headerBox.x + headerBox.width / 2;
      expect(Math.abs(navCenter - headerCenter)).toBeLessThan(10);
    });

    test('移动端导航 Tab 居中显示', async ({ page }) => {
      await page.setViewportSize({ width: 375, height: 667 });
      await page.goto('/?mock=true');
      await waitForCards(page);

      const navContainer = page.locator('#mobile-nav > div');
      await expect(navContainer).toBeVisible();

      const navBox = await navContainer.boundingBox();

      expect(navBox).toBeTruthy();
      const navCenter = navBox.x + navBox.width / 2;
      expect(Math.abs(navCenter - 375 / 2)).toBeLessThan(10);
    });
  });

  test.describe('首页加载', () => {

    test('页面标题正确', async ({ page }) => {
      await page.goto('/?mock=true');
      await expect(page).toHaveTitle(APP_TITLE);
    });

    test('头部导航显示正常', async ({ page }) => {
      await page.goto('/?mock=true');
      await expect(page.locator('h1')).toContainText(APP_TITLE);
      await expect(page.locator('#tab-monitor')).toBeVisible();
      await expect(page.locator('#tab-analytics')).toBeVisible();
    });

    test('Mock 模式数据加载成功', async ({ page }) => {
      await page.goto('/?mock=true');
      // 等待充电桩卡片渲染
      await expect(page.locator('#dc-grid')).not.toBeEmpty({ timeout: 10000 });
      await expect(page.locator('#ac-grid')).not.toBeEmpty({ timeout: 10000 });
    });

    test('底部订阅栏显示逻辑正确', async ({ page }) => {
      await page.goto('/?mock=true');
      const bottomBar = page.locator('#bottom-bar');
      // 底部栏在工作日显示，周末隐藏（这是预期行为）
      const isVisible = await bottomBar.isVisible();
      // 如果可见，检查内容
      if (isVisible) {
        await expect(bottomBar).toContainText('订阅提醒');
      }
    });
  });

  test.describe('充电桩显示', () => {

    test('DC 快充区域有充电桩卡片', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);
      const dcCards = page.locator(DC_CARD_SELECTOR);
      await expect(dcCards.first()).toBeVisible();
      expect(await dcCards.count()).toBeGreaterThan(0);
    });

    test('AC 慢充区域有充电桩卡片', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);
      const acCards = page.locator(AC_CARD_SELECTOR);
      await expect(acCards.first()).toBeVisible();
      expect(await acCards.count()).toBeGreaterThan(0);
    });

    test('充电桩卡片显示状态信息', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);
      // 检查真实卡片中有状态文本（空闲/充电中/占位/离线）
      const firstCardText = await page.locator(`${DC_CARD_SELECTOR}, ${AC_CARD_SELECTOR}`).first().innerText();
      expect(firstCardText).toMatch(/空闲可用|充电中|占位中|离线/);
    });

    test('筛选按钮显示计数', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);
      // 全部设备计数应大于 0
      const countAll = page.locator('#count-all');
      await expect(countAll).not.toHaveText('-');
    });
  });

  test.describe('筛选功能', () => {

    test('点击"空闲"筛选只显示空闲桩', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

      await page.click('#filter-free');
      // 筛选后，充电中和占用的卡片应隐藏
      await page.waitForTimeout(500);

      // 检查筛选按钮状态变化
      const freeBtn = page.locator('#filter-free');
      await expect(freeBtn).toHaveClass(/active/);
    });

    test('点击"全部"筛选恢复显示', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

      // 先筛选空闲
      await page.click('#filter-free');
      await page.waitForTimeout(300);

      // 再点全部
      await page.click('#filter-all');
      await page.waitForTimeout(300);

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

    test('筛选按钮可以切换', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

      const filters = ['filter-charging', 'filter-occupied', 'filter-free', 'filter-all'];
      for (const filterId of filters) {
        await page.click(`#${filterId}`);
        await page.waitForTimeout(200);
        const btn = page.locator(`#${filterId}`);
        await expect(btn).toHaveClass(/active/);
      }
    });
  });

  test.describe('Tab 切换', () => {

    test('切换到数据分析 Tab', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

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

      // 数据分析内容应显示
      await expect(page.locator('#analytics-content')).toBeVisible();
      // 监控内容应隐藏
      await expect(page.locator('#data-content')).toBeHidden();
      // 底部栏应隐藏
      await expect(page.locator('#bottom-bar')).toBeHidden();
    });

    test('切换回实时监控 Tab', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

      // 先切到分析
      await page.click('#tab-analytics');
      await page.waitForTimeout(300);

      // 再切回监控
      await page.click('#tab-monitor');
      await page.waitForTimeout(300);

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

    test('数据分析页面显示图表容器', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

      await page.click('#tab-analytics');
      // 等待 analytics 内容区显示
      await expect(page.locator('#analytics-content')).toBeVisible({ timeout: 5000 });
      await page.waitForTimeout(1500);

      // 检查数据概览卡片
      await expect(page.locator('#overview-cards')).toBeVisible();
      // 热力图容器存在即可（可能因无数据而高度为 0）
      await expect(page.locator('#heatmap-container')).toBeAttached();
      // 检查图表 canvas 存在
      await expect(page.locator('#visit-chart')).toBeAttached();
      await expect(page.locator('#trend-chart')).toBeAttached();
      await expect(page.locator('#rank-chart')).toBeAttached();
    });
  });

  test.describe('订阅弹窗', () => {

    test('周末订阅栏置灰显示', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

      const bottomBar = page.locator('#bottom-bar');
      await expect(bottomBar).toBeVisible();

      const isWeekend = new Date().getDay() === 0 || new Date().getDay() === 6;

      if (isWeekend) {
        // 周末：检查置灰样式和禁用状态
        const className = await bottomBar.getAttribute('class');
        expect(className).toContain('opacity-50');

        // 检查文字
        await expect(bottomBar).toContainText('无法周末订阅');

        // 按钮应该禁用
        const subscribeBtn = bottomBar.locator('button:has-text("订阅提醒")');
        await expect(subscribeBtn).toBeDisabled();
      } else {
        // 工作日：正常显示
        const className = await bottomBar.getAttribute('class');
        expect(className).not.toContain('opacity-50');
        await expect(bottomBar).toContainText('不想下楼扑空');
      }
    });

    test('订阅弹窗功能（工作日才可用）', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

      const isWeekend = new Date().getDay() === 0 || new Date().getDay() === 6;

      if (isWeekend) {
        // 周末跳过此测试
        test.skip();
        return;
      }

      await page.click('button:has-text("订阅提醒")');
      await expect(page.locator('#subscribe-modal')).toBeVisible();
      await expect(page.locator('#subscribe-modal')).toContainText('订阅空闲提醒');
    });

    test('弹窗包含邮箱输入框、充电类型和厂商品牌选择（工作日）', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

      const isWeekend = new Date().getDay() === 0 || new Date().getDay() === 6;

      if (isWeekend) {
        test.skip();
        return;
      }

      await page.click('button:has-text("订阅提醒")');
      await expect(page.locator('#email-input')).toBeVisible();
      await expect(page.locator('input[name="charger-type"][value="all"]')).toBeChecked();
      await expect(page.locator('input[name="vendor"][value="all"]')).toBeChecked();
    });

    test('关闭弹窗（工作日）', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

      const isWeekend = new Date().getDay() === 0 || new Date().getDay() === 6;

      if (isWeekend) {
        test.skip();
        return;
      }

      await page.click('button:has-text("订阅提醒")');
      await expect(page.locator('#subscribe-modal')).toBeVisible();

      // 点击关闭按钮
      await page.locator('#subscribe-modal button[class*="absolute"]').click();
      await expect(page.locator('#subscribe-modal')).toBeHidden();
    });

    test('点击遮罩层关闭弹窗（工作日）', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

      const isWeekend = new Date().getDay() === 0 || new Date().getDay() === 6;

      if (isWeekend) {
        test.skip();
        return;
      }

      await page.click('button:has-text("订阅提醒")');
      await expect(page.locator('#subscribe-modal')).toBeVisible();

      // 点击遮罩层（弹窗外部）
      await page.locator('#subscribe-modal').click({ position: { x: 10, y: 10 } });
      await expect(page.locator('#subscribe-modal')).toBeHidden();
    });

    test('选择不同的充电类型和厂商品牌（工作日）', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

      const isWeekend = new Date().getDay() === 0 || new Date().getDay() === 6;

      if (isWeekend) {
        test.skip();
        return;
      }

      await page.click('button:has-text("订阅提醒")');

      // 通过点击 label 选择 DC 快充（radio input 被 CSS 隐藏）
      await page.locator('label:has(input[name="charger-type"][value="DC"])').click();
      await expect(page.locator('input[name="charger-type"][value="DC"]')).toBeChecked();

      // 通过点击 label 选择 AC 慢充
      await page.locator('label:has(input[name="charger-type"][value="AC"])').click();
      await expect(page.locator('input[name="charger-type"][value="AC"]')).toBeChecked();

      // 通过点击 label 选择蔚来（radio input 被 CSS 隐藏）
      await page.locator('label:has(input[name="vendor"][value="nio"])').click();
      await expect(page.locator('input[name="vendor"][value="nio"]')).toBeChecked();

      // 通过点击 label 选择公牛
      await page.locator('label:has(input[name="vendor"][value="gongniu"])').click();
      await expect(page.locator('input[name="vendor"][value="gongniu"]')).toBeChecked();
    });
  });

  test.describe('刷新功能', () => {

    test('手动刷新按钮可点击', async ({ page }) => {
      await page.goto('/?mock=true');
      await waitForCards(page);

      const refreshBtn = page.locator('button[title="手动刷新"]');
      await expect(refreshBtn).toBeVisible();
      await refreshBtn.click({ force: true });
      // 刷新后数据仍应显示
      await expect(page.locator(DC_CARD_SELECTOR).first()).toBeVisible();
    });
  });

  test.describe('响应式布局', () => {

    test('移动端视口下页面正常显示', async ({ page }) => {
      await page.setViewportSize({ width: 375, height: 812 });
      await page.goto('/?mock=true');
      await waitForCards(page);

      // 页面标题仍应可见
      await expect(page.locator('h1')).toBeVisible();
      // 充电桩卡片应可见
      await expect(page.locator(DC_CARD_SELECTOR).first()).toBeVisible();
    });
  });
});
