/**
 * Оптимизированный хук для загрузки данных с кешированием
 */

import { useState, useEffect, useCallback, useRef } from 'react';
import { cache } from '@/lib/cache';
import apiClient from '@/lib/api-client';

interface UseOptimizedFetchOptions<T> {
  url: string;
  cacheKey?: string;
  /** Не используется пока кэш отключён глобально. Оставлен для последующего включения по месту. */
  cacheTTL?: number;
  enabled?: boolean;
  onSuccess?: (data: T) => void;
  onError?: (error: Error) => void;
}

interface UseOptimizedFetchResult<T> {
  data: T | null;
  loading: boolean;
  error: Error | null;
  refetch: () => Promise<void>;
  clearCache: () => void;
  mutate: (updater: T | ((prev: T | null) => T | null)) => void;
}

export function useOptimizedFetch<T = any>({
  url,
  cacheKey,
  cacheTTL,
  enabled = true,
  onSuccess,
  onError,
}: UseOptimizedFetchOptions<T>): UseOptimizedFetchResult<T> {
  const key = cacheKey || url;
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);
  const abortControllerRef = useRef<AbortController | null>(null);

  const fetchData = useCallback(async () => {
    // Отменяем предыдущий запрос
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }

    abortControllerRef.current = new AbortController();

    try {
      setLoading(true);
      setError(null);

      // Кэш отключён везде до анализа на Production (см. lib/cache.ts, api-client.ts)
      const response = await apiClient.get<T>(url, {
        signal: abortControllerRef.current.signal,
        cache: false,
      });

      const newData = response.data;
      setData(newData);
      onSuccess?.(newData);
    } catch (err: any) {
      // Не показываем ошибку при отмене запроса (навигация, размонтирование, refetch)
      const isCanceled =
        err?.name === 'AbortError' ||
        err?.name === 'CanceledError' ||
        err?.code === 'ERR_CANCELED' ||
        err?.message === 'canceled';
      if (isCanceled) {
        return;
      }
      const error = err instanceof Error ? err : new Error(err?.message || 'Unknown error');
      setError(error);
      onError?.(error);
    } finally {
      if (abortControllerRef.current && !abortControllerRef.current.signal.aborted) {
        setLoading(false);
      }
    }
  }, [url, onSuccess, onError]);

  useEffect(() => {
    if (!enabled) {
      setLoading(false);
      return;
    }

    fetchData();

    return () => {
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
    };
  }, [enabled, fetchData]);

  const clearCache = useCallback(() => {
    cache.delete(key);
    setData(null);
  }, [key]);

  // Локальное обновление данных без перезагрузки (кэш отключён)
  const mutate = useCallback((updater: T | ((prev: T | null) => T | null)) => {
    setData((prev) => {
      return typeof updater === 'function'
        ? (updater as (prev: T | null) => T | null)(prev)
        : updater;
    });
  }, []);

  return {
    data,
    loading,
    error,
    refetch: fetchData,
    clearCache,
    mutate,
  };
}
