// Zentrale API-Fetch-Utility mit Token-Refresh und Logout
import { useAuth } from '@/contexts/AuthContext';
import { useCallback } from 'react';
import { tokenStore } from '@/lib/tokenStore';
import { refreshToken } from '@/lib/refreshToken';

export type ApiFetchOptions = RequestInit & { skipAuthHandling?: boolean };

/**
 * apiFetch kapselt alle API-Requests, behandelt 401-Fehler und Token-Refresh.
 * @param input RequestInfo (URL oder Request)
 * @param options RequestInit + skipAuthHandling
 * @param logoutFn Funktion zum Ausloggen (z.B. aus AuthContext)
 */
export async function apiFetch(
  input: RequestInfo,
  options: ApiFetchOptions = {},
  logoutFn?: () => void
): Promise<Response> {
  const skipAuthHandling = options.skipAuthHandling;
  let token = tokenStore.getToken();

  // Access Token im Header setzen
  const fetchOptions: RequestInit = {
    ...options,
    headers: {
      ...(options.headers || {}),
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
    },
  };

  let response: Response;
  try {
    response = await fetch(input, fetchOptions);
  } catch (e) {
    // Nezwerk oder unerwartete Fehler abfangen
    throw new Error('Netzwerkfehler. Bitte überprüfe deine Verbindung und versuche es erneut.');
  }

  if (response.status === 401 && !skipAuthHandling) {
    // Access Token erneuern
    const newToken = await refreshToken();
    if (newToken) {
      tokenStore.setToken(newToken);
      // Request nochmal wiederholen mit neuem Token
      const retryOptions: RequestInit = {
        ...fetchOptions,
        headers: {
          ...(fetchOptions.headers || {}),
          Authorization: `Bearer ${newToken}`,
        },
      };
      try {
        response = await fetch(input, retryOptions);
      } catch (e) {
        throw new Error('Netzwerkfehler nach Token-Erneuerung. Bitte versuche es erneut.');
      }
    }
    // Wenn erneuter 401: Logout
    if (logoutFn) logoutFn();
    tokenStore.clear();
    throw new Error('Session abgelaufen. Bitte erneut einloggen.');
  }
// Abfangen der Serverfehlern
  if (response.status === 500) {
    throw new Error('Interner Serverfehler. Bitte versuche es später erneut.');
  }

  if (!response.ok) {
    try {
      const contentType = response.headers.get('content-type') || '';
      if (contentType.includes('application/json')) {
        const body = await response.json();
        const msg = typeof body?.message === 'string' ? body.message : undefined;
        throw new Error(msg || `Unerwarteter Fehler (${response.status}). Bitte versuche es erneut.`);
      } else {
        const text = await response.text();
        const trimmed = (text || '').trim();
        throw new Error(trimmed || `Unerwarteter Fehler (${response.status}). Bitte versuche es erneut.`);
      }
    } catch (err) {
      if (err instanceof Error) throw err;
      throw new Error(`Unerwarteter Fehler (${response.status}). Bitte versuche es erneut.`);
    }
  }

  return response;
}

/**
 * React-Hook für apiFetch, der automatisch logout aus dem AuthContext nutzt.
 */
export function useApiFetch() {
  const { logout } = useAuth();
  return useCallback(
    (input: RequestInfo, options: ApiFetchOptions = {}) =>
      apiFetch(input, options, logout),
    [logout]
  );
}
