/**
 * @ai-summary Axios client configuration for API calls
 * @ai-context Handles auth tokens and error responses
 */

import axios, { InternalAxiosRequestConfig } from 'axios';
import toast from 'react-hot-toast';

const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '/api';

// Will be replaced by createQueuedAxios below

// Auth readiness flag to avoid noisy 401 toasts during mobile auth initialization
let authReady = false;
export const setAuthReady = (ready: boolean) => { authReady = ready; };
export const isAuthReady = () => authReady;

// Create a wrapper around axios that queues requests until auth is ready
const createQueuedAxios = () => {
  const queuedClient = axios.create({
    baseURL: API_BASE_URL,
    timeout: 10000,
    headers: {
      'Content-Type': 'application/json',
    },
  });

  // Store original methods
  const originalRequest = queuedClient.request.bind(queuedClient);
  const originalGet = queuedClient.get.bind(queuedClient);
  const originalPost = queuedClient.post.bind(queuedClient);
  const originalPut = queuedClient.put.bind(queuedClient);
  const originalDelete = queuedClient.delete.bind(queuedClient);
  const originalPatch = queuedClient.patch.bind(queuedClient);

  // Create wrapper function for auth queue checking
  const wrapWithAuthQueue = (originalMethod: any, methodName: string) => {
    return async (...args: any[]) => {
      try {
        const { queueRequest, isAuthInitialized } = await import('../auth/auth-gate');

        if (!isAuthInitialized()) {
          console.log(`[API Client] Queuing ${methodName} request until auth ready`);
          return queueRequest(() => originalMethod(...args));
        }

        return originalMethod(...args);
      } catch (error) {
        console.warn(`[API Client] Auth gate import failed for ${methodName}, proceeding with request:`, error);
        return originalMethod(...args);
      }
    };
  };

  // Override all HTTP methods
  queuedClient.request = wrapWithAuthQueue(originalRequest, 'REQUEST');
  queuedClient.get = wrapWithAuthQueue(originalGet, 'GET');
  queuedClient.post = wrapWithAuthQueue(originalPost, 'POST');
  queuedClient.put = wrapWithAuthQueue(originalPut, 'PUT');
  queuedClient.delete = wrapWithAuthQueue(originalDelete, 'DELETE');
  queuedClient.patch = wrapWithAuthQueue(originalPatch, 'PATCH');

  return queuedClient;
};

// Replace the basic axios instance with the queued version
export const apiClient = createQueuedAxios();

// Request interceptor for token injection and logging
apiClient.interceptors.request.use(
  async (config: InternalAxiosRequestConfig) => {
    // Token will be added by Auth0 wrapper
    // Log mobile requests for debugging
    if (import.meta.env.MODE === 'development') {
      const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
      if (isMobile && config.url?.includes('/vehicles')) {
        console.log('Mobile API request:', config.method?.toUpperCase(), config.url, {
          hasAuth: !!config.headers.Authorization,
          authPreview: config.headers.Authorization?.toString().substring(0, 20) + '...'
        });
      }
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// Response interceptor for error handling with mobile-specific logic
apiClient.interceptors.response.use(
  (response) => response,
  (error) => {
    const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);

    if (error.response?.status === 401) {
      // Suppress early 401 toasts until auth is ready (mobile silent auth race)
      if (!authReady) {
        return Promise.reject(error);
      }
      // Enhanced 401 handling for mobile token issues
      const errorMessage = error.response?.data?.message || '';
      const isTokenIssue = errorMessage.includes('token') || errorMessage.includes('JWT') || errorMessage.includes('Unauthorized');

      if (isMobile && isTokenIssue) {
        // Mobile devices sometimes have token timing issues
        // Show a more helpful message that doesn't sound like a permanent error
        toast.error('Refreshing your session...', {
          duration: 3000,
          id: 'mobile-auth-refresh' // Prevent duplicate toasts
        });
      } else {
        // Standard session expiry message
        toast.error('Session expired. Please login again.');
      }
    } else if (error.response?.status === 403) {
      toast.error('You do not have permission to perform this action.');
    } else if (error.response?.status >= 500) {
      toast.error('Server error. Please try again later.');
    } else if (error.code === 'NETWORK_ERROR' && isMobile) {
      // Mobile-specific network error handling
      toast.error('Network error. Please check your connection and try again.');
    }

    return Promise.reject(error);
  }
);

export default apiClient;
