import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import axios from 'axios';

// Mock dependencies
vi.mock('../../utils/cookies', () => ({
  getCookie: vi.fn(),
  setCookie: vi.fn(),
  deleteCookie: vi.fn(),
}));

vi.mock('../../utils/domain', () => ({
  getBaseDomain: vi.fn(() => 'lvh.me'),
}));

vi.mock('../config', () => ({
  API_BASE_URL: 'http://api.lvh.me:8000',
  getSubdomain: vi.fn(),
}));

describe('api/client', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    localStorage.clear();
  });

  describe('request interceptor', () => {
    it('adds auth token from cookie when available', async () => {
      const cookies = await import('../../utils/cookies');
      const config = await import('../config');

      vi.mocked(cookies.getCookie).mockReturnValue('test-token-123');
      vi.mocked(config.getSubdomain).mockReturnValue(null);

      // Re-import client to apply mocks
      vi.resetModules();

      // Mock the interceptors
      const mockConfig = {
        headers: {} as Record<string, string>,
      };

      // Simulate what the request interceptor does
      const token = cookies.getCookie('access_token');
      if (token) {
        mockConfig.headers['Authorization'] = `Token ${token}`;
      }

      expect(mockConfig.headers['Authorization']).toBe('Token test-token-123');
    });

    it('does not add auth header when no token', async () => {
      const cookies = await import('../../utils/cookies');
      vi.mocked(cookies.getCookie).mockReturnValue(null);

      const mockConfig = {
        headers: {} as Record<string, string>,
      };

      const token = cookies.getCookie('access_token');
      if (token) {
        mockConfig.headers['Authorization'] = `Token ${token}`;
      }

      expect(mockConfig.headers['Authorization']).toBeUndefined();
    });

    it('adds business subdomain header when on business site', async () => {
      const config = await import('../config');
      vi.mocked(config.getSubdomain).mockReturnValue('demo');

      const mockConfig = {
        headers: {} as Record<string, string>,
      };

      const subdomain = config.getSubdomain();
      if (subdomain && subdomain !== 'platform') {
        mockConfig.headers['X-Business-Subdomain'] = subdomain;
      }

      expect(mockConfig.headers['X-Business-Subdomain']).toBe('demo');
    });

    it('does not add subdomain header on platform site', async () => {
      const config = await import('../config');
      vi.mocked(config.getSubdomain).mockReturnValue('platform');

      const mockConfig = {
        headers: {} as Record<string, string>,
      };

      const subdomain = config.getSubdomain();
      if (subdomain && subdomain !== 'platform') {
        mockConfig.headers['X-Business-Subdomain'] = subdomain;
      }

      expect(mockConfig.headers['X-Business-Subdomain']).toBeUndefined();
    });

    it('adds sandbox mode header when in test mode', async () => {
      // Set sandbox mode in localStorage
      window.localStorage.setItem('sandbox_mode', 'true');

      const mockConfig = {
        headers: {} as Record<string, string>,
      };

      // Simulate the getSandboxMode logic
      let isSandbox = false;
      try {
        isSandbox = window.localStorage.getItem('sandbox_mode') === 'true';
      } catch {
        isSandbox = false;
      }

      if (isSandbox) {
        mockConfig.headers['X-Sandbox-Mode'] = 'true';
      }

      expect(mockConfig.headers['X-Sandbox-Mode']).toBe('true');
    });

    it('does not add sandbox header when not in test mode', async () => {
      localStorage.removeItem('sandbox_mode');

      const mockConfig = {
        headers: {} as Record<string, string>,
      };

      const isSandbox = localStorage.getItem('sandbox_mode') === 'true';
      if (isSandbox) {
        mockConfig.headers['X-Sandbox-Mode'] = 'true';
      }

      expect(mockConfig.headers['X-Sandbox-Mode']).toBeUndefined();
    });
  });

  describe('getSandboxMode', () => {
    it('returns false when localStorage throws', () => {
      // Simulate localStorage throwing (e.g., in private browsing)
      const originalGetItem = localStorage.getItem;
      localStorage.getItem = () => {
        throw new Error('Access denied');
      };

      // Function should return false on error
      let result = false;
      try {
        result = localStorage.getItem('sandbox_mode') === 'true';
      } catch {
        result = false;
      }

      expect(result).toBe(false);

      localStorage.getItem = originalGetItem;
    });

    it('returns false when sandbox_mode is not set', () => {
      localStorage.removeItem('sandbox_mode');

      const result = localStorage.getItem('sandbox_mode') === 'true';

      expect(result).toBe(false);
    });

    it('returns true when sandbox_mode is "true"', () => {
      window.localStorage.setItem('sandbox_mode', 'true');

      const result = window.localStorage.getItem('sandbox_mode') === 'true';

      expect(result).toBe(true);
    });

    it('returns false when sandbox_mode is "false"', () => {
      localStorage.setItem('sandbox_mode', 'false');

      const result = localStorage.getItem('sandbox_mode') === 'true';

      expect(result).toBe(false);
    });
  });
});
