import { test, expect } from '@playwright/test';
import * as fs from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';

/**
 * 用户核心旅程测试（严格模式 - 固定版本）
 *
 * 双模式执行：
 * - 无真实凭证：显式跳过（test.skip）
 * - 有真实凭证：严格断言 2xx/3xx
 */

const API_BASE_URL = process.env.API_BASE_URL || 'http://localhost:8080';
const FRONTEND_URL = process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:5176';

const DEFAULT_TEST_API_KEY = 'test-api-key-000000000000';
const DEFAULT_TEST_USER_TOKEN = 'test-e2e-token';

interface TestData {
  activityId: number;
  apiKey: string;
  userToken: string;
  userId: number;
  shortCode: string;
  baseUrl: string;
  apiBaseUrl: string;
}

function loadTestData(): TestData {
  const __filename = fileURLToPath(import.meta.url);
  const __dirname = path.dirname(__filename);
  const testDataPath = path.join(__dirname, '..', '.e2e-test-data.json');

  const defaultData: TestData = {
    activityId: 1,
    apiKey: DEFAULT_TEST_API_KEY,
    userToken: process.env.E2E_USER_TOKEN || DEFAULT_TEST_USER_TOKEN,
    userId: 10001,
    shortCode: 'test123',
    baseUrl: process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:5176',
    apiBaseUrl: process.env.API_BASE_URL || 'http://localhost:8080',
  };

  try {
    if (fs.existsSync(testDataPath)) {
      const data = JSON.parse(fs.readFileSync(testDataPath, 'utf-8'));
      return { ...defaultData, ...data };
    }
  } catch (error) {
    console.warn('无法加载测试数据，使用默认值');
  }

  return defaultData;
}

function hasRealApiCredentials(data: TestData): boolean {
  return Boolean(
    data.apiKey &&
      data.userToken &&
      data.apiKey !== DEFAULT_TEST_API_KEY &&
      data.userToken !== DEFAULT_TEST_USER_TOKEN
  );
}

// 加载测试数据
const testData = loadTestData();
const useRealCredentials = hasRealApiCredentials(testData);
const E2E_STRICT = process.env.E2E_STRICT === 'true';

test.describe('🎯 用户核心旅程测试（严格模式）', () => {
  // 首页不需要凭证，始终执行
  test('🏠 首页应可访问（无需凭证）', async ({ page }) => {
    await page.goto('/');
    await page.waitForLoadState('networkidle');
    await expect(page.locator('#app')).toBeAttached();
  });

  if (!useRealCredentials) {
    // 严格模式下无真实凭证时必须失败，非严格模式才跳过
    if (E2E_STRICT) {
      test('📊 活动列表API（需要真实凭证）', async () => {
        throw new Error('严格模式需要真实凭证（E2E_USER_TOKEN），但未提供有效凭证，测试失败');
      });
    } else {
      test.skip('📊 活动列表API（需要真实凭证）', async ({ request }) => {
        // 此测试需要真实凭证，无凭证时跳过
      });
    }
  } else {
    // 有真实凭证时严格断言
    test('📊 活动列表API - 严格断言', async ({ request }) => {
      const response = await request.get(`${API_BASE_URL}/api/v1/activities`, {
        headers: {
          'X-API-Key': testData.apiKey,
          'Authorization': `Bearer ${testData.userToken}`,
        },
      });

      const status = response.status();
      // 严格断言：只接受 2xx/3xx
      expect(
        status,
        `活动列表API应返回2xx/3xx，实际${status}`
      ).toBeGreaterThanOrEqual(200);
      expect(
        status,
        `活动列表API应返回2xx/3xx，实际${status}`
      ).toBeLessThan(400);
    });

    test('后端健康检查应正常 - 严格断言', async ({ request }) => {
      const response = await request.get(`${API_BASE_URL}/actuator/health`);
      expect(
        response.status(),
        `健康检查应返回200，实际${response.status()}`
      ).toBe(200);
      const body = await response.json();
      expect(
        body.status,
        `健康检查状态应为UP，实际${body.status}`
      ).toBe('UP');
    });

    test('前端服务应可访问 - 严格断言', async ({ page }) => {
      const response = await page.goto(FRONTEND_URL);
      expect(
        response,
        '页面响应不应为null'
      ).not.toBeNull();
      expect(
        response?.status(),
        `前端应返回2xx/3xx，实际${response?.status()}`
      ).toBeGreaterThanOrEqual(200);
      expect(
        response?.status(),
        `前端应返回2xx/3xx，实际${response?.status()}`
      ).toBeLessThan(400);
    });
  }
});