import { useCallback, useEffect, useRef, useState } from 'react';

/**
 * Yükleme durumlarını yönetmek için özelleştirilmiş React hook.
 * Durum yönetimi, ilerleme takibi ve hata yönetimi sağlar.
 */

export type LoadingStatus = 'IDLE' | 'LOADING' | 'ERROR' | 'SUCCESS';

export interface LoadingState {
  status: LoadingStatus;
  message?: string;
  progress: number;
  error?: string | Error | null;
}

/**
 * useLoadingState hook'u
 * @param initialStatus Başlangıç durumu (varsayılan: 'IDLE')
 */
export const useLoadingState = (initialStatus: LoadingStatus = 'IDLE') => {
  const [state, setState] = useState<LoadingState>({
    status: initialStatus,
    message: '',
    progress: 0,
    error: null,
  });

  const timeoutRef = useRef<NodeJS.Timeout | null>(null);

  /**
   * Durumu başlangıç (IDLE) haline döndürür ve aktif zamanlayıcıları temizler.
   */
  const clear = useCallback(() => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
      timeoutRef.current = null;
    }
    setState({
      status: 'IDLE',
      message: '',
      progress: 0,
      error: null,
    });
  }, []);

  /**
   * Yükleme durumunu ve mesajını ayarlar.
   * @param status Yeni durum ('IDLE', 'LOADING', 'ERROR', 'SUCCESS')
   * @param message Görüntülenecek mesaj (isteğe bağlı)
   * @param duration Milisaniye cinsinden otomatik temizleme süresi (isteğe bağlı)
   */
  const setLoading = useCallback((
    status: LoadingStatus,
    message: string = '',
    duration?: number
  ) => {
    // Aktif zamanlayıcıyı temizle (Manual override)
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
      timeoutRef.current = null;
    }

    setState(prev => ({
      ...prev,
      status,
      message,
      // Status IDLE'a dönerse progress'i sıfırla, aksi halde mevcut değeri koru
      progress: status === 'IDLE' ? 0 : prev.progress,
      // Status ERROR değilse mevcut hatayı temizle
      error: status === 'ERROR' ? prev.error : null,
    }));

    // Eğer bir süre belirtilmişse, o süre sonunda IDLE'a dön
    if (duration && duration > 0) {
      timeoutRef.current = setTimeout(() => {
        clear();
      }, duration);
    }
  }, [clear]);

  /**
   * İlerleme yüzdesini günceller (0-100 arası).
   * @param percentage İlerleme yüzdesi
   */
  const setProgress = useCallback((percentage: number) => {
    setState(prev => ({
      ...prev,
      progress: Math.min(100, Math.max(0, percentage)),
    }));
  }, []);

  /**
   * Hata durumunu ve mesajını ayarlar.
   * @param error Hata mesajı veya Error nesnesi
   */
  const setError = useCallback((error: string | Error) => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
      timeoutRef.current = null;
    }

    const errorMessage = typeof error === 'string' ? error : error.message;

    setState(prev => ({
      ...prev,
      status: 'ERROR',
      error,
      message: errorMessage,
    }));
  }, []);

  /**
   * Mevcut durumu döndürür.
   */
  const getState = useCallback(() => state, [state]);

  // Bileşen unmount olduğunda temizlik yap
  useEffect(() => {
    return () => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    };
  }, []);

  return {
    state,
    setLoading,
    setProgress,
    setError,
    clear,
    getState,
    // Yardımcı bayraklar (Kolay kullanım için)
    isLoading: state.status === 'LOADING',
    isError: state.status === 'ERROR',
    isIdle: state.status === 'IDLE',
    isSuccess: state.status === 'SUCCESS',
  };
};

export default useLoadingState;
