import { describe, it, expect, vi, beforeEach } from 'vitest';
import { BaseApiClient } from '../../../apps/website/lib/api/base/BaseApiClient';
import { Logger } from '../../../apps/website/lib/interfaces/Logger';
import { ErrorReporter } from '../../../apps/website/lib/interfaces/ErrorReporter';

describe('BaseApiClient - Invariants', () => {
  let client: BaseApiClient;
  let mockLogger: Logger;
  let mockErrorReporter: ErrorReporter;

  beforeEach(() => {
    mockLogger = {
      info: vi.fn(),
      warn: vi.fn(),
      error: vi.fn(),
      debug: vi.fn(),
    };
    mockErrorReporter = {
      report: vi.fn(),
    };
    client = new BaseApiClient(
      'https://api.example.com',
      mockErrorReporter,
      mockLogger
    );
  });

  describe('classifyError()', () => {
    it('should classify 5xx as SERVER_ERROR', () => {
      expect((client as any).classifyError(500)).toBe('SERVER_ERROR');
      expect((client as any).classifyError(503)).toBe('SERVER_ERROR');
    });

    it('should classify 429 as RATE_LIMIT_ERROR', () => {
      expect((client as any).classifyError(429)).toBe('RATE_LIMIT_ERROR');
    });

    it('should classify 401/403 as AUTH_ERROR', () => {
      expect((client as any).classifyError(401)).toBe('AUTH_ERROR');
      expect((client as any).classifyError(403)).toBe('AUTH_ERROR');
    });

    it('should classify 400 as VALIDATION_ERROR', () => {
      expect((client as any).classifyError(400)).toBe('VALIDATION_ERROR');
    });

    it('should classify 404 as NOT_FOUND', () => {
      expect((client as any).classifyError(404)).toBe('NOT_FOUND');
    });

    it('should classify other 4xx as UNKNOWN_ERROR', () => {
      expect((client as any).classifyError(418)).toBe('UNKNOWN_ERROR');
    });
  });

  describe('isRetryableError()', () => {
    it('should return true for retryable error types', () => {
      expect((client as any).isRetryableError('NETWORK_ERROR')).toBe(true);
      expect((client as any).isRetryableError('SERVER_ERROR')).toBe(true);
      expect((client as any).isRetryableError('RATE_LIMIT_ERROR')).toBe(true);
      expect((client as any).isRetryableError('TIMEOUT_ERROR')).toBe(true);
    });

    it('should return false for non-retryable error types', () => {
      expect((client as any).isRetryableError('AUTH_ERROR')).toBe(false);
      expect((client as any).isRetryableError('VALIDATION_ERROR')).toBe(false);
      expect((client as any).isRetryableError('NOT_FOUND')).toBe(false);
    });
  });
});
