/**
 * HTTP客户端测试文件
 */

import { HttpClient, HttpError, RequestInterceptor, ResponseInterceptor } from './http';
import { Storage } from '../utils/storage';

describe('HttpClient', () => {
  let httpClient: HttpClient;
  let storage: Storage;

  beforeEach(() => {
    storage = new Storage('localStorage');
    httpClient = new HttpClient({
      baseURL: 'https://api.example.com',
      timeout: 5000
    });
  });

  describe('构造函数', () => {
    test('应该正确初始化默认配置', () => {
      const client = new HttpClient();
      expect(client.getConfig()).toMatchObject({
        baseURL: '',
        timeout: 10000,
        withCredentials: true
      });
    });

    test('应该正确合并自定义配置', () => {
      const config = {
        baseURL: 'https://test.com',
        timeout: 3000,
        withCredentials: false
      };
      
      const client = new HttpClient(config);
      expect(client.getConfig()).toMatchObject(config);
    });
  });

  describe('Token管理', () => {
    test('应该能够设置和获取Token获取函数', () => {
      const tokenGetter = () => 'test-token';
      httpClient.setTokenGetter(tokenGetter);
      
      // 这里需要通过反射或其他方式验证内部状态
      // 由于是私有属性，我们通过实际请求来间接测试
    });

    test('应该能够设置租户ID', () => {
      httpClient.setTenantId('test-tenant');
      expect(httpClient.getConfig().tenantId).toBe('test-tenant');
    });
  });

  describe('拦截器', () => {
    test('应该能够添加和移除请求拦截器', () => {
      const interceptor: RequestInterceptor = {
        onRequest: (options) => {
          options.headers = { ...options.headers, 'X-Custom': 'test' };
          return options;
        }
      };

      httpClient.addRequestInterceptor(interceptor);
      // 测试逻辑需要配合实际请求
      
      httpClient.removeRequestInterceptor(interceptor);
    });

    test('应该能够添加和移除响应拦截器', () => {
      const interceptor: ResponseInterceptor = {
        onResponse: (response) => {
          return { ...response, data: { ...response.data, intercepted: true } };
        }
      };

      httpClient.addResponseInterceptor(interceptor);
      // 测试逻辑需要配合实际请求
      
      httpClient.removeResponseInterceptor(interceptor);
    });
  });

  describe('静态方法', () => {
    test('应该能够创建带基础URL的客户端实例', () => {
      const client = HttpClient.create('https://api.test.com', {
        timeout: 8000
      });
      
      expect(client.getConfig().baseURL).toBe('https://api.test.com');
      expect(client.getConfig().timeout).toBe(8000);
    });
  });

  describe('配置管理', () => {
    test('应该能够获取和更新配置', () => {
      const initialConfig = httpClient.getConfig();
      expect(initialConfig.timeout).toBe(5000);

      httpClient.updateConfig({ timeout: 8000 });
      const updatedConfig = httpClient.getConfig();
      expect(updatedConfig.timeout).toBe(8000);
    });
  });

  describe('HTTP错误处理', () => {
    test('HttpError应该正确初始化', () => {
      const error = new HttpError(
        'Test error',
        404,
        'Not Found',
        { detail: 'Resource not found' },
        'RESOURCE_NOT_FOUND'
      );

      expect(error.message).toBe('Test error');
      expect(error.status).toBe(404);
      expect(error.statusText).toBe('Not Found');
      expect(error.data).toEqual({ detail: 'Resource not found' });
      expect(error.code).toBe('RESOURCE_NOT_FOUND');
      expect(error.name).toBe('HttpError');
    });

    test('HttpError应该有正确的堆栈跟踪', () => {
      const error = new HttpError('Test error');
      expect(error.stack).toBeDefined();
    });
  });
});

describe('工具函数', () => {
  // 这里可以添加对私有方法的测试（如果需要的话）
  // 通常通过公共接口间接测试私有逻辑
});