// hooks/useAppData.ts

import { useCallback, useEffect, useState } from 'react';
import { useAppDispatch, useAppSelector } from '@/store/hooks';

// Thunks
import { getClients } from '@/store/features/client/thunk';
import { getDevisList } from '@/store/features/devis/thunk';
import { getArticles } from '@/store/features/article/thunk';
import { getFactures } from '@/store/features/factures/thunk';
import { getCommercials } from '@/store/features/commercial/thunk';
import { getCommandes } from '@/store/features/commande/thunk';
import { getAvoirs } from '@/store/features/avoir/thunk';
import { getfamilles } from '@/store/features/famille/thunk';
import { getUniversigns } from '@/store/features/universign/thunk';

// Selectors pour les status
import { clientStatus } from '@/store/features/client/selectors';
import { devisStatus } from '@/store/features/devis/selectors';
import { articleStatus } from '@/store/features/article/selectors';
import { factureStatus } from '@/store/features/factures/selectors';
import { commercialsStatus } from '@/store/features/commercial/selectors';
import { commandeStatus } from '@/store/features/commande/selectors';
import { avoirStatus } from '@/store/features/avoir/selectors';
import { familleStatus } from '@/store/features/famille/selectors';
import { universignStatus } from '@/store/features/universign/selectors';
import { loadAllReglementData } from '../features/reglement/thunk';
import { reglementStatus } from '../features/reglement/selectors';
import { getAllBL } from '../features/bl/thunk';
import { BLStatus } from '../features/bl/selectors';

// Types pour les données à charger
export type DataType = 
  | 'clients'
  | 'devis'
  | 'articles'
  | 'factures'
  | 'reglement'
  | 'commercials'
  | 'commandes'
  | 'avoirs'
  | 'familles'
  | 'universign'
  | 'bls'

// Configuration des thunks par type de données
const dataConfig: Record<DataType, { thunk: any; statusSelector: any }> = {
  clients: { thunk: getClients, statusSelector: clientStatus },
  devis: { thunk: getDevisList, statusSelector: devisStatus },
  articles: { thunk: getArticles, statusSelector: articleStatus },
  factures: { thunk: getFactures, statusSelector: factureStatus },
  reglement: { thunk: loadAllReglementData, statusSelector: reglementStatus },
  commercials: { thunk: getCommercials, statusSelector: commercialsStatus },
  commandes: { thunk: getCommandes, statusSelector: commandeStatus },
  avoirs: { thunk: getAvoirs, statusSelector: avoirStatus },
  familles: { thunk: getfamilles, statusSelector: familleStatus },
  universign: { thunk: getUniversigns, statusSelector: universignStatus },
  bls: { thunk: getAllBL, statusSelector: BLStatus },
};

// Données par défaut à charger sur toutes les pages
const DEFAULT_DATA: DataType[] = [
  'clients',
  'articles',
  'commercials',
  'familles',
];

interface UseAppDataOptions {
  include?: DataType[];
  only?: DataType[];
  exclude?: DataType[];
  forceRefresh?: boolean;
  skipInitialLoad?: boolean;
}

interface UseAppDataReturn {
  refresh: () => Promise<void>;
  refreshData: (...types: DataType[]) => Promise<void>;
  isLoading: boolean;
  isInitialLoading: boolean;
  error: string | null;
  statuses: Record<DataType, string>;
}

export const useAppData = (options: UseAppDataOptions = {}): UseAppDataReturn => {
  const dispatch = useAppDispatch();
  const [isLoading, setIsLoading] = useState(false);
  const [isInitialLoading, setIsInitialLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // Récupérer tous les status
  const statuses: Record<DataType, string> = {
    clients: useAppSelector(clientStatus),
    devis: useAppSelector(devisStatus),
    articles: useAppSelector(articleStatus),
    factures: useAppSelector(factureStatus),
    reglement: useAppSelector(reglementStatus),
    commercials: useAppSelector(commercialsStatus),
    commandes: useAppSelector(commandeStatus),
    avoirs: useAppSelector(avoirStatus),
    familles: useAppSelector(familleStatus),
    universign: useAppSelector(universignStatus),
    bls: useAppSelector(BLStatus),
  };

  // Déterminer les données à charger
  const getDataToLoad = useCallback((): DataType[] => {
    const { include = [], only, exclude = [] } = options;

    if (only) {
      return only;
    }

    const baseData = [...DEFAULT_DATA, ...include];
    return baseData.filter((type) => !exclude.includes(type));
  }, [options]);

  // Charger des données spécifiques
  const loadData = useCallback(
    async (types: DataType[], force = false) => {
      const promises = types.map(async (type) => {
        const config = dataConfig[type];
        if (!config) return;

        // Ne charger que si status est 'idle' ou si force est true
        const currentStatus = statuses[type];
        if (!force && currentStatus !== 'idle') return;

        try {
          await dispatch(config.thunk()).unwrap();
        } catch (err) {
          console.error(`Erreur chargement ${type}:`, err);
          throw err;
        }
      });

      await Promise.all(promises);
    },
    [dispatch, statuses]
  );

  // Rafraîchir toutes les données configurées
  const refresh = useCallback(async () => {
    setIsLoading(true);
    setError(null);

    try {
      const dataToLoad = getDataToLoad();
      await loadData(dataToLoad, true); // Force refresh
    } catch (err: any) {
      setError(err.message || 'Erreur lors du rafraîchissement');
    } finally {
      setIsLoading(false);
    }
  }, [getDataToLoad, loadData]);

  // Rafraîchir des données spécifiques
  const refreshData = useCallback(
    async (...types: DataType[]) => {
      setIsLoading(true);
      setError(null);

      try {
        await loadData(types, true); // Force refresh
      } catch (err: any) {
        setError(err.message || 'Erreur lors du rafraîchissement');
      } finally {
        setIsLoading(false);
      }
    },
    [loadData]
  );

  // Chargement initial au montage
  useEffect(() => {
    if (options.skipInitialLoad) {
      setIsInitialLoading(false);
      return;
    }

    const initialLoad = async () => {
      setIsInitialLoading(true);
      setError(null);

      try {
        const dataToLoad = getDataToLoad();
        await loadData(dataToLoad, options.forceRefresh);
      } catch (err: any) {
        setError(err.message || 'Erreur lors du chargement initial');
      } finally {
        setIsInitialLoading(false);
      }
    };

    initialLoad();
  }, []); // Exécuter une seule fois au montage

  return {
    refresh,
    refreshData,
    isLoading,
    isInitialLoading,
    error,
    statuses,
  };
};


// ============================================
// HOOKS SPÉCIALISÉS PAR PAGE
// ============================================

/** Hook pour la page Devis */
export const useDevisData = () => {
  return useAppData({
    include: ['devis', 'universign'],
  });
};

/** Hook pour la page Factures */
export const useFacturesData = () => {
  return useAppData({
    include: ['factures', 'avoirs'],
  });
};

/** Hook pour la page Commandes */
export const useCommandesData = () => {
  return useAppData({
    include: ['commandes'],
  });
};

/** Hook pour la page Articles */
export const useArticlesData = () => {
  return useAppData({
    include: ['articles', 'familles'],
  });
};

/** Hook pour le Dashboard (toutes les données) */
export const useDashboardData = () => {
  return useAppData({
    include: ['devis', 'factures', 'commandes', 'avoirs', 'reglement', 'bls', 'clients'],
  });
};

/** Hook pour la création de documents (devis, factures, etc.) */
export const useDocumentCreationData = () => {
  return useAppData({
    only: ['clients', 'articles', 'familles', 'commercials'],
  });
};


export default useAppData;