import { API_BASE_URL } from '@/utils/constants';
import { getToken } from '@/utils/helpers';

export interface FetchOptions extends RequestInit {
  token?: string;
}

export class ApiError extends Error {
  constructor(
    public status: number,
    message: string,
    public data?: any
  ) {
    super(message);
    this.name = 'ApiError';
  }
}

async function fetchWithAuth(
  endpoint: string,
  options: FetchOptions = {}
): Promise<Response> {
  const token = options.token || getToken();

  // Logs de debug
  console.log('🔐 [API] Préparation de la requête:', {
    endpoint,
    hasToken: !!token,
    tokenPreview: token ? `${token.substring(0, 20)}...` : 'Aucun',
  });

  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
    ...options.headers as Record<string, string>,
  };

  if (token) {
    headers['Authorization'] = `Bearer ${token}`;
    console.log('✅ [API] Header Authorization ajouté');
  } else {
    console.warn('⚠️ [API] Aucun token disponible - requête sans authentification');
  }

  const config: RequestInit = {
    ...options,
    headers,
  };

  const url = endpoint.startsWith('http') ? endpoint : `${API_BASE_URL}${endpoint}`;

  console.log('📡 [API] Envoi de la requête:', {
    url,
    method: config.method || 'GET',
    headers: headers,
    body: options.body,
  });

  try {
    const response = await fetch(url, config);

    if (!response.ok) {
      let errorMessage = 'Une erreur est survenue';
      let errorData;

      try {
        errorData = await response.json();
        errorMessage = errorData.message || errorData.error || errorMessage;
        console.error('❌ [API] Erreur du serveur:', {
          status: response.status,
          statusText: response.statusText,
          errorData,
          errorMessage,
        });
      } catch {
        errorMessage = response.statusText || errorMessage;
        console.error('❌ [API] Erreur sans JSON:', {
          status: response.status,
          statusText: response.statusText,
        });
      }

      throw new ApiError(response.status, errorMessage, errorData);
    }

    return response;
  } catch (error) {
    if (error instanceof ApiError) {
      throw error;
    }
    throw new ApiError(0, 'Erreur de connexion au serveur');
  }
}

export const api = {
  get: async <T>(endpoint: string, options?: FetchOptions): Promise<T> => {
    const response = await fetchWithAuth(endpoint, {
      ...options,
      method: 'GET',
    });
    return response.json();
  },

  post: async <T>(
    endpoint: string,
    data?: any,
    options?: FetchOptions
  ): Promise<T> => {
    const response = await fetchWithAuth(endpoint, {
      ...options,
      method: 'POST',
      body: data ? JSON.stringify(data) : undefined,
    });
    return response.json();
  },

  put: async <T>(
    endpoint: string,
    data?: any,
    options?: FetchOptions
  ): Promise<T> => {
    const response = await fetchWithAuth(endpoint, {
      ...options,
      method: 'PUT',
      body: data ? JSON.stringify(data) : undefined,
    });
    return response.json();
  },

  patch: async <T>(
    endpoint: string,
    data?: any,
    options?: FetchOptions
  ): Promise<T> => {
    const response = await fetchWithAuth(endpoint, {
      ...options,
      method: 'PATCH',
      body: data ? JSON.stringify(data) : undefined,
    });
    return response.json();
  },

  delete: async <T>(endpoint: string, options?: FetchOptions): Promise<T> => {
    const response = await fetchWithAuth(endpoint, {
      ...options,
      method: 'DELETE',
    });
    return response.json();
  },
};
