/**
 * @vitest-environment node
 */

import { describe, it, expect } from 'vitest';
import { BaseOptions } from '../../src/types';
import { E2ETestError } from '../../src/errors';
import { DEFAULT_TIMEOUTS, SELECTOR_STRATEGIES } from '../../src/constants';

describe('@d8d/e2e-test-utils 基础功能', () => {
  describe('类型定义', () => {
    it('应该正确导出 BaseOptions 类型', () => {
      const options: BaseOptions = { timeout: 1000 };
      expect(options.timeout).toBe(1000);
    });

    it('BaseOptions 应该支持可选属性', () => {
      const options: BaseOptions = {};
      expect(options.timeout).toBeUndefined();
    });
  });

  describe('错误类', () => {
    it('应该能够创建 E2ETestError 实例', () => {
      const error = new E2ETestError({
        operation: 'testOperation',
        target: 'testTarget',
        expected: 'expectedValue',
        actual: 'actualValue',
      });

      expect(error).toBeInstanceOf(Error);
      expect(error.name).toBe('E2ETestError');
      expect(error.context.operation).toBe('testOperation');
      expect(error.context.target).toBe('testTarget');
    });

    it('E2ETestError 应该包含格式化的错误消息', () => {
      const error = new E2ETestError({
        operation: 'selectOption',
        target: 'dropdown',
        expected: 'Option A',
        actual: 'Option B',
      });

      expect(error.message).toContain('selectOption failed');
      expect(error.message).toContain('dropdown');
    });

    it('E2ETestError 应该包含可用选项列表', () => {
      const error = new E2ETestError({
        operation: 'selectOption',
        target: 'dropdown',
        expected: 'Option A',
        actual: 'Option B',
        available: ['Option A', 'Option B', 'Option C'],
      });

      expect(error.message).toContain('Available: Option A, Option B, Option C');
    });

    it('E2ETestError 应该包含修复建议', () => {
      const error = new E2ETestError({
        operation: 'selectOption',
        target: 'dropdown',
        expected: 'Option A',
        actual: 'Option B',
        suggestion: '检查选项值是否正确拼写',
      });

      expect(error.message).toContain('💡 检查选项值是否正确拼写');
    });

    it('E2ETestError 应该支持自定义消息', () => {
      const customMessage = '自定义错误消息';
      const error = new E2ETestError(
        {
          operation: 'testOperation',
          target: 'testTarget',
        },
        customMessage
      );

      expect(error.message).toBe(customMessage);
    });

    it('E2ETestError 应该处理最小上下文', () => {
      const error = new E2ETestError({
        operation: 'clickElement',
        target: '[data-testid="button"]',
      });

      expect(error.message).toContain('clickElement failed');
      expect(error.message).toContain('Target: [data-testid="button"]');
    });

    it('E2ETestError 应该包含完整的错误上下文', () => {
      const error = new E2ETestError({
        operation: 'selectRadixOption',
        target: '残疾类型',
        expected: '视力残疾',
        actual: '听力残疾',
        available: ['视力残疾', '听力残疾', '肢体残疾'],
        suggestion: '确认选项值是否正确',
      });

      expect(error.message).toContain('❌ selectRadixOption failed');
      expect(error.message).toContain('Target: 残疾类型');
      expect(error.message).toContain('Expected: 视力残疾');
      expect(error.message).toContain('Actual: 听力残疾');
      expect(error.message).toContain('Available: 视力残疾, 听力残疾, 肢体残疾');
      expect(error.message).toContain('💡 确认选项值是否正确');
    });
  });

  describe('常量定义', () => {
    it('DEFAULT_TIMEOUTS 应该包含所有必需的超时配置', () => {
      expect(DEFAULT_TIMEOUTS.static).toBeDefined();
      expect(DEFAULT_TIMEOUTS.async).toBeDefined();
      expect(DEFAULT_TIMEOUTS.networkIdle).toBeDefined();

      expect(DEFAULT_TIMEOUTS.static).toBe(2000);
      expect(DEFAULT_TIMEOUTS.async).toBe(5000);
      expect(DEFAULT_TIMEOUTS.networkIdle).toBe(10000);
    });

    it('SELECTOR_STRATEGIES 应该包含所有策略', () => {
      expect(SELECTOR_STRATEGIES).toContain('data-testid');
      expect(SELECTOR_STRATEGIES).toContain('aria-label + role');
      expect(SELECTOR_STRATEGIES).toContain('text content + role');
      expect(SELECTOR_STRATEGIES).toHaveLength(3);
    });
  });

  describe('Vitest 配置验证', () => {
    it('当前测试应该正常运行', () => {
      expect(true).toBe(true);
    });

    it('Vitest 应该支持 TypeScript', () => {
      const value: string = 'TypeScript support verified';
      expect(value).toBe('TypeScript support verified');
    });
  });
});
