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

/**
 * 状态持续时长逻辑测试
 * 验证 formatDuration / getIdleTime / getChargingTime / getOccupiedTime / formatRemainingTime
 */

test.describe('formatDuration 核心格式化', () => {

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

  test('0 秒返回"刚刚"', async ({ page }) => {
    const result = await page.evaluate(() => {
      // 动态导入 time.js 模块
      return import('./src/js/time.js').then(m => m.formatDuration(0));
    });
    expect(result).toEqual({ text: '刚刚', detailed: '刚刚' });
  });

  test('负数返回"刚刚"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatDuration(-100));
    });
    expect(result).toEqual({ text: '刚刚', detailed: '刚刚' });
  });

  test('30 秒（< 1分钟）返回"刚刚"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatDuration(30));
    });
    expect(result).toEqual({ text: '刚刚', detailed: '刚刚' });
  });

  test('59 秒（< 1分钟）返回"刚刚"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatDuration(59));
    });
    expect(result).toEqual({ text: '刚刚', detailed: '刚刚' });
  });

  test('60 秒（1分钟）返回"1 分钟"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatDuration(60));
    });
    expect(result).toEqual({ text: '1 分钟', detailed: '1 分钟' });
  });

  test('300 秒（5分钟）返回"5 分钟"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatDuration(300));
    });
    expect(result).toEqual({ text: '5 分钟', detailed: '5 分钟' });
  });

  test('3599 秒（59分钟）返回"59 分钟"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatDuration(3599));
    });
    expect(result).toEqual({ text: '59 分钟', detailed: '59 分钟' });
  });

  test('3600 秒（1小时整）返回"1 小时"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatDuration(3600));
    });
    expect(result).toEqual({ text: '1 小时', detailed: '1 小时' });
  });

  test('5400 秒（1小时30分）返回"1 小时"和详细"1 小时 30 分钟"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatDuration(5400));
    });
    expect(result.text).toBe('1 小时');
    expect(result.detailed).toBe('1 小时 30 分钟');
  });

  test('7200 秒（2小时整）返回"2 小时"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatDuration(7200));
    });
    expect(result).toEqual({ text: '2 小时', detailed: '2 小时' });
  });

  test('86399 秒（23小时59分）返回"23 小时"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatDuration(86399));
    });
    expect(result.text).toBe('23 小时');
    expect(result.detailed).toBe('23 小时 59 分钟');
  });

  test('86400 秒（24小时/1天）返回"1 天"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatDuration(86400));
    });
    expect(result).toEqual({ text: '1 天', detailed: '1 天' });
  });

  test('172800 秒（2天）返回"2 天"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatDuration(172800));
    });
    expect(result).toEqual({ text: '2 天', detailed: '2 天' });
  });

  test('90000 秒（25小时/1天1小时）返回"1 天"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatDuration(90000));
    });
    expect(result).toEqual({ text: '1 天', detailed: '1 天' });
  });
});

test.describe('getIdleTime 空闲时长', () => {

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

  test('idle_seconds 为 0 时返回"空闲中"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getIdleTime({ idle_seconds: 0 }));
    });
    expect(result).toEqual({ seconds: 0, text: '空闲中' });
  });

  test('idle_seconds 缺失时返回"空闲中"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getIdleTime({}));
    });
    expect(result).toEqual({ seconds: 0, text: '空闲中' });
  });

  test('空闲 60 秒返回"空闲 1 分钟"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getIdleTime({ idle_seconds: 60 }));
    });
    expect(result).toEqual({ seconds: 60, text: '空闲 1 分钟' });
  });

  test('空闲 300 秒返回"空闲 5 分钟"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getIdleTime({ idle_seconds: 300 }));
    });
    expect(result).toEqual({ seconds: 300, text: '空闲 5 分钟' });
  });

  test('空闲 3600 秒返回"空闲 1 小时"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getIdleTime({ idle_seconds: 3600 }));
    });
    expect(result).toEqual({ seconds: 3600, text: '空闲 1 小时' });
  });
});

test.describe('getChargingTime 充电时长', () => {

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

  test('charging_seconds 为 0 时返回"充电中"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getChargingTime({ charging_seconds: 0 }));
    });
    expect(result).toEqual({ seconds: 0, text: '充电中' });
  });

  test('charging_seconds 缺失时返回"充电中"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getChargingTime({}));
    });
    expect(result).toEqual({ seconds: 0, text: '充电中' });
  });

  test('充电 1800 秒返回"已充 30 分钟"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getChargingTime({ charging_seconds: 1800 }));
    });
    expect(result).toEqual({ seconds: 1800, text: '已充 30 分钟' });
  });

  test('充电 3600 秒返回"已充 1 小时"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getChargingTime({ charging_seconds: 3600 }));
    });
    expect(result).toEqual({ seconds: 3600, text: '已充 1 小时' });
  });

  test('充电 5400 秒返回"已充 1 小时"（详细含30分钟）', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getChargingTime({ charging_seconds: 5400 }));
    });
    expect(result.seconds).toBe(5400);
    expect(result.text).toBe('已充 1 小时');
  });

  test('充电 90000 秒（>1天）返回"已充 1 天"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getChargingTime({ charging_seconds: 90000 }));
    });
    expect(result).toEqual({ seconds: 90000, text: '已充 1 天' });
  });
});

test.describe('getOccupiedTime 占位时长', () => {

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

  test('occupied_seconds 为 0 时返回"占位中"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getOccupiedTime({ occupied_seconds: 0 }));
    });
    expect(result).toEqual({ seconds: 0, text: '占位中' });
  });

  test('occupied_seconds 缺失时返回"占位中"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getOccupiedTime({}));
    });
    expect(result).toEqual({ seconds: 0, text: '占位中' });
  });

  test('占位 900 秒返回"占位 15 分钟"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getOccupiedTime({ occupied_seconds: 900 }));
    });
    expect(result).toEqual({ seconds: 900, text: '占位 15 分钟' });
  });

  test('占位 3600 秒返回"占位 1 小时"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.getOccupiedTime({ occupied_seconds: 3600 }));
    });
    expect(result).toEqual({ seconds: 3600, text: '占位 1 小时' });
  });
});

test.describe('formatRemainingTime 剩余充电时间', () => {

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

  test('null 返回 null', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatRemainingTime(null));
    });
    expect(result).toBeNull();
  });

  test('undefined 返回 null', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatRemainingTime(undefined));
    });
    expect(result).toBeNull();
  });

  test('0 分钟返回"即将充满"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatRemainingTime(0));
    });
    expect(result).toBe('即将充满');
  });

  test('负数返回"即将充满"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatRemainingTime(-5));
    });
    expect(result).toBe('即将充满');
  });

  test('30 分钟返回"剩余 30 分钟"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatRemainingTime(30));
    });
    expect(result).toBe('剩余 30 分钟');
  });

  test('60 分钟返回"剩余 1 小时"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatRemainingTime(60));
    });
    expect(result).toBe('剩余 1 小时');
  });

  test('90 分钟返回"剩余 1 小时 30 分钟"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatRemainingTime(90));
    });
    expect(result).toBe('剩余 1 小时 30 分钟');
  });

  test('120 分钟返回"剩余 2 小时"', async ({ page }) => {
    const result = await page.evaluate(() => {
      return import('./src/js/time.js').then(m => m.formatRemainingTime(120));
    });
    expect(result).toBe('剩余 2 小时');
  });
});

test.describe('Mock 数据时长渲染验证', () => {

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

  test('充电中卡片显示"已充"时长前缀', async ({ page }) => {
    // 所有充电中卡片都应包含"已充"文本
    const chargingCards = page.locator('#ac-grid > div, #dc-grid > div').filter({ hasText: '充电中' });
    const count = await chargingCards.count();
    expect(count).toBeGreaterThan(0);
    for (let i = 0; i < count; i++) {
      await expect(chargingCards.nth(i)).toContainText('已充');
    }
  });

  test('空闲卡片显示"空闲"时长前缀', async ({ page }) => {
    const freeCards = page.locator('#ac-grid > div, #dc-grid > div').filter({ hasText: '空闲可用' });
    const count = await freeCards.count();
    expect(count).toBeGreaterThan(0);
    for (let i = 0; i < count; i++) {
      await expect(freeCards.nth(i)).toContainText('空闲');
    }
  });

  test('占位卡片显示"占位"时长前缀', async ({ page }) => {
    const occupiedCards = page.locator('#ac-grid > div, #dc-grid > div').filter({ hasText: '占位中' });
    const count = await occupiedCards.count();
    expect(count).toBeGreaterThan(0);
    for (let i = 0; i < count; i++) {
      await expect(occupiedCards.nth(i)).toContainText('占位');
    }
  });

  test('DC 充电卡片显示进度百分比', async ({ page }) => {
    // DC 充电中卡片应显示 XX% 格式的进度（动效层: "已充65%，还需35分钟充满"）
    const dcChargingCards = page.locator('#dc-grid > div').filter({ hasText: '充电中' });
    const count = await dcChargingCards.count();
    for (let i = 0; i < count; i++) {
      await expect(dcChargingCards.nth(i)).toContainText(/\d+%/);
    }
  });

  test('DC 充电卡片显示剩余/还需时间', async ({ page }) => {
    // DC 充电中卡片应显示"剩余"或"还需"时间（动效层用"还需"，状态区用"剩余"）
    const dcChargingCards = page.locator('#dc-grid > div').filter({ hasText: '充电中' });
    const count = await dcChargingCards.count();
    for (let i = 0; i < count; i++) {
      await expect(dcChargingCards.nth(i)).toContainText(/剩余|还需/);
    }
  });

  test('时长格式符合规范（分钟/小时/天）', async ({ page }) => {
    // 所有时长文本应匹配 "X 分钟" / "X 小时" / "X 天" / "刚刚" 格式
    const allCards = page.locator('#ac-grid > div, #dc-grid > div');
    const count = await allCards.count();
    for (let i = 0; i < count; i++) {
      const text = await allCards.nth(i).innerText();
      // 应包含时长相关的关键词
      const hasDuration = /分钟|小时|天|刚刚|充电中|空闲中|占位中/.test(text);
      expect(hasDuration).toBeTruthy();
    }
  });
});
