/**
 * API Client
 * Axios instance configured for SmoothSchedule API
 */

import axios, { AxiosError, InternalAxiosRequestConfig } from 'axios';
import { API_BASE_URL, getSubdomain } from './config';
import { getCookie } from '../utils/cookies';

// Create axios instance
const apiClient = axios.create({
  baseURL: API_BASE_URL,
  headers: {
    'Content-Type': 'application/json',
  },
  withCredentials: true, // For CORS with credentials
});

/**
 * Get sandbox mode from localStorage
 * This is set by the SandboxContext when mode changes
 */
const getSandboxMode = (): boolean => {
  try {
    return localStorage.getItem('sandbox_mode') === 'true';
  } catch {
    return false;
  }
};

// Request interceptor - add auth token, business subdomain, and sandbox mode
apiClient.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // Add business subdomain header if on business site
    const subdomain = getSubdomain();
    if (subdomain && subdomain !== 'platform') {
      config.headers['X-Business-Subdomain'] = subdomain;
    }

    // Add auth token if available (from cookie)
    const token = getCookie('access_token');
    if (token) {
      // Use 'Token' prefix for Django REST Framework Token Authentication
      config.headers['Authorization'] = `Token ${token}`;
    }

    // Add sandbox mode header if in test mode
    const isSandbox = getSandboxMode();
    if (isSandbox) {
      config.headers['X-Sandbox-Mode'] = 'true';
    }

    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// Response interceptor - handle errors and token refresh
apiClient.interceptors.response.use(
  (response) => response,
  async (error: AxiosError) => {
    const originalRequest = error.config as InternalAxiosRequestConfig & { _retry?: boolean };

    // Handle 401 Unauthorized - token expired
    if (error.response?.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;

      try {
        // Try to refresh token (from cookie)
        const refreshToken = getCookie('refresh_token');
        if (refreshToken) {
          const response = await axios.post(`${API_BASE_URL}/auth/refresh/`, {
            refresh: refreshToken,
          });

          const { access } = response.data;

          // Import setCookie dynamically to avoid circular dependency
          const { setCookie } = await import('../utils/cookies');
          setCookie('access_token', access, 7);

          // Retry original request with new token
          if (originalRequest.headers) {
            originalRequest.headers['Authorization'] = `Bearer ${access}`;
          }
          return apiClient(originalRequest);
        }
      } catch (refreshError) {
        // Refresh failed - clear tokens and redirect to login on root domain
        const { deleteCookie } = await import('../utils/cookies');
        const { getBaseDomain } = await import('../utils/domain');
        deleteCookie('access_token');
        deleteCookie('refresh_token');
        const protocol = window.location.protocol;
        const baseDomain = getBaseDomain();
        const port = window.location.port ? `:${window.location.port}` : '';
        window.location.href = `${protocol}//${baseDomain}${port}/login`;
        return Promise.reject(refreshError);
      }
    }

    return Promise.reject(error);
  }
);

export default apiClient;
