import { useState, useMemo, useEffect, useCallback } from 'react';
import { Helmet } from 'react-helmet';
import { useNavigate } from 'react-router-dom';
import { Plus, Eye, Download, CheckCircle, FileText, Euro, AlertTriangle, X, Wallet, Info } from 'lucide-react';
import KPIBar, { PeriodType } from '@/components/KPIBar';
import { toast } from '@/components/ui/use-toast';
import { cn, formatDateFRCourt } from '@/lib/utils';
import { Facture, FactureAction } from '@/types/factureType';
import { useAppDispatch, useAppSelector } from '@/store/hooks';
import { factureStatus, getAllfacture, getfactureSelected } from '@/store/features/factures/selectors';
import { getFactures, selectFactureAsync, validerFacture, getFacture } from '@/store/features/factures/thunk';
import PrimaryButton_v2 from '@/components/PrimaryButton_v2';
import { filterItemByPeriod, getPreviousPeriodItems } from '@/components/filter/ItemsFilter';
import { ModalFacture } from '@/components/modal/ModalFacture';
import { DropdownMenuTable } from '@/components/DropdownMenu';
import { clientStatus, getAllClients } from '@/store/features/client/selectors';
import { articleStatus } from '@/store/features/article/selectors';
import { getArticles } from '@/store/features/article/thunk';
import { getClients } from '@/store/features/client/thunk';
import { Client } from '@/types/clientType';
import ModalStatus from '@/components/modal/ModalStatus';
import StatusBadge, { STATUS_LABELS } from '@/components/ui/StatusBadge';
import { SageDocumentType } from '@/types/sageTypes';
import ColumnSelector, { ColumnConfig } from '@/components/common/ColumnSelector';
import PeriodSelector from '@/components/common/PeriodSelector';
import { CompanyInfo } from '@/data/mockData';
import PDFPreview, { DocumentData } from '@/components/modal/PDFPreview';
import { usePDFPreview } from '@/components/ui/PDFActionButtons';
import ExportDropdown from '@/components/common/ExportDropdown';
import { useDashboardData } from '@/store/hooks/useAppData';
import DataTable from '@/components/ui/DataTable';
import { getAllReglements, reglementStatus } from '@/store/features/reglement/selectors';
import { loadAllReglementData } from '@/store/features/reglement/thunk';
import ModalPaymentPanel from '@/components/modal/ModalPaymentPanel';
import { FacturesReglement } from '@/types/reglementType';
import { selectfacture } from '@/store/features/factures/slice';
import FormModal from '@/components/ui/FormModal';
import ModalValidationWarningCard from '@/components/modal/ModalValidationWarningCard';
import { ModalLoading } from '@/components/modal/ModalLoading';
import AdvancedFilters from '@/components/common/AdvancedFilters';
import { Commercial } from '@/types/commercialType';
import { commercialsStatus, getAllcommercials } from '@/store/features/commercial/selectors';
import { getCommercials } from '@/store/features/commercial/thunk';

// ============================================
// CONSTANTES
// ============================================

const STATUT_REGLEMENT = {
  SOLDE: 'Soldé',
  PARTIEL: 'Partiellement réglé',
  NON_REGLE: 'Non réglé',
} as const;

const COLORS = {
  gray: 'bg-gray-400',
  yellow: 'bg-yellow-400',
  orange: 'bg-orange-400',
  green: 'bg-green-400',
  purple: 'bg-purple-400',
  blue: 'bg-blue-400',
};

// Labels de statut pour les factures
const FACTURE_STATUS_LABELS = {
  0: { label: 'Saisi', color: COLORS.gray },
  1: { label: 'Confirmé', color: COLORS.yellow },
  2: { label: 'A comptabiliser', color: COLORS.orange },
  3: { label: 'Comptabilisé', color: COLORS.green },
  // 4: { label: 'Payé', color: COLORS.purple },
  5: { label: 'Validé', color: COLORS.blue },
  6: { label: 'Payé', color: COLORS.green },
  7: { label: 'Partiellement payé', color: COLORS.orange },
} as const;

export type StatusCode = keyof typeof FACTURE_STATUS_LABELS;

// ============================================
// TYPES
// ============================================

type FilterType = 'all' | 'paid' | 'pending' | 'validated' | 'partial';

interface FactureWithReglement extends Facture {
  statut_reglement: string;
  montant_regle: number;
  reste_a_regler: number;
  statut_display: number; // Statut à afficher (peut être 6 ou 7 selon règlement)
}

interface KPIConfig {
  id: FilterType;
  title: string;
  icon: React.ElementType;
  color: string;
  getValue: (factures: Facture[]) => number | string;
  getSubtitle: (factures: Facture[], value: number | string) => string;
  getChange: (factures: Facture[], value: number | string, period: PeriodType, allFactures: Facture[]) => string;
  getTrend: (factures: Facture[], value: number | string, period: PeriodType, allFactures: Facture[]) => 'up' | 'down' | 'neutral';
  filter: (factures: Facture[]) => Facture[];
  tooltip?: { content: string; source: string };
}

// ============================================
// CONFIGURATION DES COLONNES
// ============================================

const DEFAULT_COLUMNS: ColumnConfig[] = [
  { key: 'numero', label: 'N° Pièce', visible: true, locked: true },
  { key: 'client_code', label: 'Client', visible: true },
  { key: 'date', label: 'Date', visible: true },
  { key: 'total_ht_calcule', label: 'Montant HT', visible: false },
  { key: 'total_ttc_calcule', label: 'Montant TTC', visible: true },
  { key: 'reste_a_regler', label: 'Solde dû', visible: true },
  { key: 'statut', label: 'Statut', visible: true },
];

// ============================================
// CONFIGURATION DES KPIs
// ============================================

const KPI_CONFIG: KPIConfig[] = [
  {
    id: 'all',
    title: 'Total HT',
    icon: Euro,
    color: 'blue',
    getValue: (factures) => Math.round(factures.reduce((sum, item) => sum + item.total_ht, 0)),
    getSubtitle: (factures) => {
      const totalTTC = factures.reduce((sum, item) => sum + item.total_ttc, 0);
      return `${totalTTC.toLocaleString('fr-FR')}€ TTC`;
    },
    getChange: (factures, value, period, allFactures) => {
      const previousPeriodFactures = getPreviousPeriodItems(allFactures, period);
      const previousTotalHT = previousPeriodFactures.reduce((sum, item) => sum + item.total_ht, 0);
      return previousTotalHT > 0 ? (((Number(value) - previousTotalHT) / previousTotalHT) * 100).toFixed(1) : '0';
    },
    getTrend: (factures, value, period, allFactures) => {
      const previousPeriodFactures = getPreviousPeriodItems(allFactures, period);
      const previousTotalHT = previousPeriodFactures.reduce((sum, item) => sum + item.total_ht, 0);
      return Number(value) >= previousTotalHT ? 'up' : 'down';
    },
    filter: (factures) => factures,
    tooltip: { content: "Total des factures sur la période.", source: "Ventes > Factures" }
  },
  {
    id: 'paid',
    title: 'Payés',
    icon: CheckCircle,
    color: 'green',
    getValue: (factures) => {
      const soldees = factures.filter(f => (f as any).statut_display === 6);
      return Math.round(soldees.reduce((sum, item) => sum + item.total_ttc, 0));
    },
    getSubtitle: (factures) => {
      const soldees = factures.filter(f => (f as any).statut_display === 6);
      return `${soldees.length} facture${soldees.length > 1 ? 's' : ''}`;
    },
    getChange: (factures, value, period, allFactures) => {
      const soldees = factures.filter(f => (f as any).statut_display === 6);
      const totalFacture = factures.length;
      return totalFacture > 0 ? `${soldees.length}/${totalFacture}` : '0';
    },
    getTrend: (factures, value, period, allFactures) => {
      const previousPeriodFactures = getPreviousPeriodItems(allFactures, period);
      const previousSoldees = previousPeriodFactures.filter(f => (f as any).statut_display === 6);
      const previousTotal = previousSoldees.reduce((sum, item) => sum + item.total_ttc, 0);
      return Number(value) >= previousTotal ? 'up' : 'down';
    },
    filter: (factures) => factures.filter(f => (f as any).statut_display === 6),
    tooltip: { content: "Montant des factures entièrement réglées.", source: "Ventes > Factures" }
  },
  {
    id: 'partial',
    title: 'Partiellement réglées',
    icon: AlertTriangle,
    color: 'orange',
    getValue: (factures) => {
      const partielles = factures.filter(f => (f as any).statut_display === 7);
      return Math.round(partielles.reduce((sum, item) => sum + ((item as any).reste_a_regler || item.total_ttc), 0));
    },
    getSubtitle: (factures) => {
      const partielles = factures.filter(f => (f as any).statut_display === 7);
      return `${partielles.length} facture${partielles.length > 1 ? 's' : ''}`;
    },
    getChange: (factures, value, period, allFactures) => {
      const partielles = factures.filter(f => (f as any).statut_display === 7);
      const totalFacture = factures.length;
      return totalFacture > 0 ? `${partielles.length}/${totalFacture}` : '0';
    },
    getTrend: (factures, value, period, allFactures) => {
      const previousPeriodFactures = getPreviousPeriodItems(allFactures, period);
      const previousPartielles = previousPeriodFactures.filter(f => (f as any).statut_display === 7);
      const previousTotal = previousPartielles.reduce((sum, item) => sum + ((item as any).reste_a_regler || item.total_ttc), 0);
      return Number(value) <= previousTotal ? 'up' : 'down';
    },
    filter: (factures) => factures.filter(f => (f as any).statut_display === 7),
    tooltip: { content: "Montant restant à régler sur les factures partiellement payées.", source: "Ventes > Factures" }
  },
  {
    id: 'pending',
    title: 'Non réglées',
    icon: FileText,
    color: 'red',
    getValue: (factures) => {
      // Factures ni soldées (6) ni partiellement payées (7)
      const nonReglees = factures.filter(f => (f as any).statut_display !== 6 && (f as any).statut_display !== 7);
      return nonReglees.length;
    },
    getSubtitle: (factures) => {
      const nonReglees = factures.filter(f => (f as any).statut_display !== 6 && (f as any).statut_display !== 7);
      const totalRestant = nonReglees.reduce((sum, item) => sum + ((item as any).reste_a_regler || item.total_ttc), 0);
      return `${totalRestant.toLocaleString('fr-FR')}€ à régler`;
    },
    getChange: (factures, value, period, allFactures) => {
      const previousPeriodFactures = getPreviousPeriodItems(allFactures, period);
      const previousNonReglees = previousPeriodFactures.filter(f => (f as any).statut_display !== 6 && (f as any).statut_display !== 7);
      return previousNonReglees.length > 0 
        ? (((Number(value) - previousNonReglees.length) / previousNonReglees.length) * 100).toFixed(1) 
        : '0';
    },
    getTrend: (factures, value, period, allFactures) => {
      const previousPeriodFactures = getPreviousPeriodItems(allFactures, period);
      const previousNonReglees = previousPeriodFactures.filter(f => (f as any).statut_display !== 6 && (f as any).statut_display !== 7);
      // Moins de non réglées = mieux
      return Number(value) <= previousNonReglees.length ? 'up' : 'down';
    },
    filter: (factures) => factures.filter(f => (f as any).statut_display !== 6 && (f as any).statut_display !== 7),
    tooltip: { content: "Nombre de factures non réglées.", source: "Ventes > Factures" }
  },
  {
    id: 'validated',
    title: 'Validées',
    icon: CheckCircle,
    color: 'purple',
    getValue: (factures) => factures.filter(f => f.valide === 1).length,
    getSubtitle: (factures) => {
      const nonValidees = factures.filter(f => f.valide !== 1);
      return `${nonValidees.length} non validée${nonValidees.length > 1 ? 's' : ''}`;
    },
    getChange: (factures) => {
      const validated = factures.filter(f => f.valide === 1);
      return `${validated.length}/${factures.length}`;
    },
    getTrend: (factures, value, period, allFactures) => {
      const previousPeriodFactures = getPreviousPeriodItems(allFactures, period);
      const previousValidated = previousPeriodFactures.filter(f => f.valide === 1);
      return Number(value) >= previousValidated.length ? 'up' : 'down';
    },
    filter: (factures) => factures.filter(f => f.valide === 1),
    tooltip: { content: "Nombre de factures validées.", source: "Ventes > Factures" }
  },
];

// ============================================
// COMPOSANT PRINCIPAL
// ============================================

const InvoicesPage = () => {
  const navigate = useNavigate();
  const dispatch = useAppDispatch();
  const [period, setPeriod] = useState<PeriodType>('all');
  const [activeFilter, setActiveFilter] = useState<FilterType>('all');
  const [columnConfig, setColumnConfig] = useState<ColumnConfig[]>(DEFAULT_COLUMNS);
  const [selectedInvoiceIds, setSelectedInvoiceIds] = useState<string[]>([]);
  const [isPaymentPanelOpen, setIsPaymentPanelOpen] = useState(false);
  const [isValidationDialogOpen, setIsValidationDialogOpen] = useState(false);
  const [isValidating, setIsValidating] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [facturesToValidate, setFacturesToValidate] = useState<FactureWithReglement[]>([]);
  const [activeFilters, setActiveFilters] = useState<Record<string, string[] | undefined>>({});

  const { showPreview, openPreview, closePreview } = usePDFPreview();
  const clients = useAppSelector(getAllClients) as Client[];
  const commercials = useAppSelector(getAllcommercials) as Commercial[];
  const factures = useAppSelector(getAllfacture) as Facture[];
  const facturesSelected = useAppSelector(getfactureSelected) as Facture;
  const statusFacture = useAppSelector(factureStatus);
  const reglements = useAppSelector(getAllReglements) as FacturesReglement[];

  const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
  const [openStatus, setOpenStatus] = useState(false);
  const [editing, setEditing] = useState<Facture | null>(null);

  const isLoading = statusFacture === 'loading' && factures.length === 0;

  const statusClient = useAppSelector(clientStatus);
  const statusArticle = useAppSelector(articleStatus);
  const statusReglement = useAppSelector(reglementStatus);
  const statusCommercial = useAppSelector(commercialsStatus);

  useEffect(() => {
    const load = async () => {
      try {
        if (statusArticle === 'idle') await dispatch(getArticles()).unwrap();
        if (statusClient === 'idle' || statusClient === 'failed') await dispatch(getClients()).unwrap();
        if (statusFacture === 'idle' || statusFacture === 'failed') await dispatch(getFactures()).unwrap();
        if (statusReglement === 'idle' || statusReglement === 'failed') await dispatch(loadAllReglementData()).unwrap();
        if (statusCommercial === 'idle') await dispatch(getCommercials()).unwrap();
      } catch (error) {
        console.error(error);
      }
    };
    load();
  }, [statusArticle, statusClient, statusFacture, statusReglement, statusCommercial, dispatch]);

  const { refresh } = useDashboardData();

  // ============================================
  // OPTIONS POUR LES FILTRES
  // ============================================

  const commercialOptions = useMemo(() => {
    return commercials.map(c => ({
      value: c.numero.toString(),
      label: `${c.prenom || ''} ${c.nom || ''}`.trim() || `Commercial ${c.numero}`,
    }));
  }, [commercials]);

  // Map pour retrouver le commercial d'un client rapidement
  const clientCommercialMap = useMemo(() => {
    const map = new Map<string, string>();
    clients.forEach(client => {
      if (client.commercial?.numero) {
        map.set(client.numero, client.commercial.numero.toString());
      }
    });
    return map;
  }, [clients]);

  const filterDefinitions = [
    {
      key: 'status',
      label: 'Statut',
      options: (Object.entries(FACTURE_STATUS_LABELS) as [string, typeof FACTURE_STATUS_LABELS[StatusCode]][]).map(
        ([value, { label, color }]) => ({
          value: value.toString(),
          label,
          color,
        })
      ),
    },
    {
      key: 'rep',
      label: 'Commercial',
      options: commercialOptions,
    },
  ];

  // ============================================
  // Map des règlements par numéro de facture
  // ============================================

  const reglementsMap = useMemo(() => {
    return new Map(reglements.map(r => [r.numero, r]));
  }, [reglements]);

  // ============================================
  // Factures enrichies avec statut règlement
  // ============================================

  const facturesWithReglement = useMemo((): FactureWithReglement[] => {
    return factures.map(f => {
      const reglement = reglementsMap.get(f.numero);

      let resteARegler = f.total_ttc_calcule;
      let montantRegle = 0;
      let statutReglement: string = STATUT_REGLEMENT.NON_REGLE;
      let statutDisplay = f.statut; // Par défaut, le statut original

      if (reglement) {
        statutReglement = reglement.statut_reglement || STATUT_REGLEMENT.NON_REGLE;
        montantRegle = reglement.montants?.montant_regle || 0;

        // Déterminer le statut_display selon le règlement
        if (statutReglement === STATUT_REGLEMENT.SOLDE) {
          resteARegler = 0;
          statutDisplay = 6; // Payé (via règlement)
        } else if (statutReglement === STATUT_REGLEMENT.PARTIEL) {
          resteARegler = reglement.montants?.reste_a_regler || 0;
          statutDisplay = 7; // Partiellement payé
        } else {
          resteARegler = reglement.montants?.reste_a_regler || f.total_ttc_calcule;
        }
      }

      return {
        ...f,
        statut_reglement: statutReglement,
        montant_regle: montantRegle,
        reste_a_regler: resteARegler,
        statut_display: statutDisplay,
      };
    });
  }, [factures, reglementsMap]);

  
  // ============================================
  // Client actuellement sélectionné
  // ============================================

  const selectedClientCode = useMemo(() => {
    if (selectedInvoiceIds.length === 0) return null;
    const firstSelectedFacture = facturesWithReglement.find(f => f.numero === selectedInvoiceIds[0]);
    return firstSelectedFacture?.client_code || null;
  }, [selectedInvoiceIds, facturesWithReglement]);

  const selectedClient = useMemo(() => {
    if (!selectedClientCode) return null;
    return clients.find(c => c.numero === selectedClientCode);
  }, [selectedClientCode, clients]);

  // ============================================
  // KPIs
  // ============================================

  const kpis = useMemo(() => {
  // Utiliser facturesWithReglement au lieu de factures
  const periodFilteredFactures = filterItemByPeriod(facturesWithReglement, period, 'date');

  return KPI_CONFIG.map(config => {
    const value = config.getValue(periodFilteredFactures);
    return {
      id: config.id,
      title: config.title,
      value: config.id === 'all' || config.id === 'paid' || config.id === 'partial' ? `${value.toLocaleString('fr-FR')}€` : value,
      change: config.getChange(periodFilteredFactures, value, period, facturesWithReglement), // aussi ici
      trend: config.getTrend(periodFilteredFactures, value, period, facturesWithReglement), // et ici
      icon: config.icon,
      subtitle: config.getSubtitle(periodFilteredFactures, value),
      color: config.color,
      tooltip: config.tooltip,
      isActive: activeFilter === config.id,
      onClick: () => setActiveFilter(prev => (prev === config.id ? 'all' : config.id)),
    };
  });
}, [facturesWithReglement, period, activeFilter]); 

  // ============================================
  // Filtrage combiné : Période + KPI + Filtres avancés
  // ============================================

  const filteredFactures = useMemo(() => {
    // 1. Filtrer par période
    let result: FactureWithReglement[] = filterItemByPeriod(facturesWithReglement, period, 'date');
    
    // 2. Filtrer par KPI actif
    const kpiConfig = KPI_CONFIG.find(k => k.id === activeFilter);
    if (kpiConfig && activeFilter !== 'all') {
      result = kpiConfig.filter(result) as FactureWithReglement[];
    }
    
    // 3. Filtres avancés (statut)
    if (activeFilters.status && activeFilters.status.length > 0) {
      result = result.filter(item =>
        activeFilters.status!.includes(item.statut_display.toString())
      );
    }

    // 4. Filtre par commercial
    if (activeFilters.rep && activeFilters.rep.length > 0) {
      result = result.filter(item => {
        const commercialCode = clientCommercialMap.get(item.client_code);
        return commercialCode && activeFilters.rep!.includes(commercialCode);
      });
    }

    // 5. Tri par date décroissante
    return [...result].sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
  }, [facturesWithReglement, period, activeFilter, activeFilters, clientCommercialMap]);


  // ============================================
  // Factures sélectionnables
  // ============================================

  const selectableFactures = useMemo(() => {
    return filteredFactures.filter(f => {
      const isNotSolde = f.statut_reglement !== STATUT_REGLEMENT.SOLDE;
      const isSameClient = !selectedClientCode || f.client_code === selectedClientCode;
      return isNotSolde && isSameClient;
    });
  }, [filteredFactures, selectedClientCode]);

  // ============================================
  // Factures sélectionnées (avec données de règlement)
  // ============================================

  const selectedFactures = useMemo(() => {
    return facturesWithReglement.filter(f => selectedInvoiceIds.includes(f.numero));
  }, [selectedInvoiceIds, facturesWithReglement]);

  // ============================================
  // Total sélectionné = somme des reste_a_regler
  // ============================================

  const totalSelectedBalance = useMemo(() => {
    return selectedFactures.reduce((sum, f) => sum + f.reste_a_regler, 0);
  }, [selectedFactures]);

  const formatCurrency = (amount: number) => {
    return `${amount.toLocaleString('fr-FR', { minimumFractionDigits: 2 })}€`;
  };

  // ============================================
  // Label du filtre actif
  // ============================================

  const activeFilterLabel = useMemo(() => {
    const config = KPI_CONFIG.find(k => k.id === activeFilter);
    return config?.title || 'Tous';
  }, [activeFilter]);

  // ============================================
  // Handlers
  // ============================================

  const handleSelectInvoice = (numero: string) => {
    const facture = facturesWithReglement.find(f => f.numero === numero);
    if (!facture) return;

    if (facture.statut_reglement === STATUT_REGLEMENT.SOLDE) {
      toast({
        title: 'Facture déjà réglée',
        description: 'Cette facture est déjà soldée.',
        variant: 'destructive',
      });
      return;
    }

    if (selectedClientCode && facture.client_code !== selectedClientCode) {
      toast({
        title: 'Client différent',
        description: 'Vous ne pouvez sélectionner que des factures du même client.',
        variant: 'destructive',
      });
      return;
    }

    setSelectedInvoiceIds(prev => (prev.includes(numero) ? prev.filter(id => id !== numero) : [...prev, numero]));
  };

  const handleSelectAll = (checked: boolean) => {
    if (checked && selectableFactures.length > 0) {
      const firstClientCode = selectableFactures[0].client_code;
      const sameClientFactures = selectableFactures.filter(f => f.client_code === firstClientCode);
      setSelectedInvoiceIds(sameClientFactures.map(f => f.numero));
    } else {
      setSelectedInvoiceIds([]);
    }
  };

  // ============================================
  // Validation automatique des factures
  // ============================================

  const validateFacturesSequentially = useCallback(
    async (facturesToValidate: FactureWithReglement[]) => {
      setIsValidating(true);

      try {
        for (const facture of facturesToValidate) {
          await dispatch(validerFacture(facture.numero)).unwrap();
          const itemUpdated = (await dispatch(getFacture(facture.numero)).unwrap()) as Facture;
          dispatch(selectfacture(itemUpdated));
        }

        toast({
          title: 'Factures validées',
          description: `${facturesToValidate.length} facture(s) validée(s) avec succès.`,
          className: 'bg-green-500 text-white border-green-600',
        });

        await dispatch(getFactures()).unwrap();

        return true;
      } catch (err: any) {
        toast({
          title: 'Erreur de validation',
          description: err.message || 'Impossible de valider les factures.',
          variant: 'destructive',
        });
        return false;
      } finally {
        setIsValidating(false);
      }
    },
    [dispatch]
  );

  const handlePayment = useCallback(() => {
    if (selectedInvoiceIds.length === 0) return;

    const nonValidatedFactures = selectedFactures.filter(f => f.valide !== 1);

    if (nonValidatedFactures.length > 0) {
      setFacturesToValidate(nonValidatedFactures);
      setIsValidationDialogOpen(true);
    } else {
      setIsPaymentPanelOpen(true);
    }
  }, [selectedInvoiceIds, selectedFactures]);

  const handleConfirmValidationAndPayment = useCallback(async () => {
    setIsValidationDialogOpen(false);
    setIsSaving(true);

    const success = await validateFacturesSequentially(facturesToValidate);

    if (success) {
      setIsPaymentPanelOpen(true);
    }

    setIsSaving(false);
    setFacturesToValidate([]);
  }, [facturesToValidate, validateFacturesSequentially]);

  const handleCancelValidation = useCallback(() => {
    setIsValidationDialogOpen(false);
    setFacturesToValidate([]);
  }, []);

  const handlePaymentSuccess = useCallback(() => {
    setSelectedInvoiceIds([]);
    setIsPaymentPanelOpen(false);
    toast({
      title: 'Règlement effectué',
      description: 'Les factures ont été réglées avec succès.',
      className: 'bg-green-500 text-white border-green-600',
    });
    dispatch(loadAllReglementData());
    dispatch(getFactures());
  }, [dispatch]);

  // ============================================
  // PDF Data
  // ============================================

  const pdfData = useMemo(() => {
    if (!facturesSelected) return null;
    return {
      numero: facturesSelected.numero,
      type: 'facture' as const,
      date: facturesSelected.date,
      client: {
        code: facturesSelected.client_code,
        nom: facturesSelected.client_intitule,
        adresse: facturesSelected.client_adresse,
        code_postal: facturesSelected.client_code_postal,
        ville: facturesSelected.client_ville,
        email: facturesSelected.client_email,
        telephone: facturesSelected.client_telephone,
      },
      reference_externe: facturesSelected.reference,
      lignes: (facturesSelected.lignes ?? []).map(l => ({
        article: l.article_code,
        designation: l.designation,
        quantite: l.quantite,
        prix_unitaire: l.prix_unitaire_ht ?? 0,
        tva: 20,
        total_ht: l.quantite * (l.prix_unitaire_ht ?? 0),
      })),
      total_ht: facturesSelected.total_ht_calcule,
      total_tva: facturesSelected.total_taxes_calcule,
      total_ttc: facturesSelected.total_ttc_calcule,
    };
  }, [facturesSelected]) as DocumentData;

  const handleCreate = () => navigate('/home/factures/nouveau');

  const handleEdit = (row: Facture) => {
    setEditing(row);
    setIsCreateModalOpen(true);
  };

  const handleAction = (action: FactureAction, row: Facture) => {
    const messages: Record<FactureAction, { title: string; description: string }> = {
      send: { title: 'Facture envoyée', description: `Email envoyé à ${row.client_intitule}` },
      download: { title: 'Téléchargement', description: 'Génération du PDF en cours...' },
      remind: { title: 'Relance envoyée', description: 'Le client a été notifié.' },
      paid: { title: 'Facture payée', description: 'Statut mis à jour avec succès.' },
    };
    toast(messages[action]);
  };

  const openPDF = async (row: Facture) => {
    await dispatch(selectFactureAsync(row)).unwrap();
    openPreview();
  };

  // ============================================
  // COLONNES
  // ============================================

  const allColumnsDefinition = useMemo(() => {
    const clientsMap = new Map(clients.map(c => [c.numero, c]));

    return {
      numero: {
        key: 'numero',
        label: 'N° Pièce',
        sortable: true,
        render: (value: string) => <span className="font-bold">{value}</span>,
      },
      client_code: {
        key: 'client_code',
        label: 'Client',
        sortable: true,
        render: (clientCode: string) => {
          const client = clientsMap.get(clientCode);
          if (!client) return <span className="text-gray-400">{clientCode}</span>;
          const avatar = client.intitule?.charAt(0).toUpperCase() || '?';
          return (
            <div className="flex items-center gap-3">
              <div className="w-9 h-9 rounded-full bg-gray-100 dark:bg-gray-800 flex items-center justify-center text-xs font-bold text-gray-600 dark:text-gray-300">
                {avatar}
              </div>
              <div>
                <p className="text-sm font-medium text-gray-900 dark:text-white">{client.intitule}</p>
                <p className="text-xs text-gray-500">{client.email || client.telephone || clientCode}</p>
              </div>
            </div>
          );
        },
      },
      date: {
        key: 'date',
        label: 'Date',
        sortable: true,
        render: (date: string) => <span>{formatDateFRCourt(date)}</span>,
      },
      total_ht_calcule: {
        key: 'total_ht_calcule',
        label: 'Montant HT',
        sortable: true,
        render: (v: number) => `${v.toLocaleString()}€`,
      },
      total_ttc_calcule: {
        key: 'total_ttc_calcule',
        label: 'Montant TTC',
        sortable: true,
        render: (v: number) => <span className="font-semibold">{formatCurrency(v)}</span>,
      },
      reste_a_regler: {
        key: 'reste_a_regler',
        label: 'Solde dû',
        sortable: true,
        render: (value: number, row: FactureWithReglement) => {
          const isSolde = row.statut_reglement === STATUT_REGLEMENT.SOLDE;
          const isPartiel = row.statut_reglement === STATUT_REGLEMENT.PARTIEL;

          return (
            <div className="flex flex-col">
              <span
                className={cn(
                  'font-bold',
                  isSolde
                    ? 'text-green-600 dark:text-green-400'
                    : isPartiel
                    ? 'text-amber-600 dark:text-amber-400'
                    : 'text-red-600 dark:text-red-400'
                )}
              >
                {formatCurrency(value)}
              </span>
              {isPartiel && row.montant_regle > 0 && (
                <span className="text-xs text-gray-500">(déjà réglé: {formatCurrency(row.montant_regle)})</span>
              )}
            </div>
          );
        },
      },
      statut: {
        key: 'statut',
        label: 'Statut',
        sortable: true,
        render: (v: number, row: FactureWithReglement) => (
          <StatusBadge status={row.statut_display} type_doc={SageDocumentType.FACTURE} />
        ),
      },
    };
  }, [clients]);

  const visibleColumns = useMemo(() => {
    return columnConfig
      .filter(col => col.visible)
      .map(col => allColumnsDefinition[col.key as keyof typeof allColumnsDefinition])
      .filter(Boolean);
  }, [columnConfig, allColumnsDefinition]);

  const columnFormatters: Record<string, (value: any, row: any) => string> = {
    date: value => (value ? formatDateFRCourt(value) : ''),
    total_ht_calcule: value => formatCurrency(value || 0),
    total_ttc_calcule: value => formatCurrency(value || 0),
    reste_a_regler: value => formatCurrency(value || 0),
    statut: (value, row) =>
      row.statut_reglement || FACTURE_STATUS_LABELS[value as StatusCode]?.label || 'Inconnu',
    client_intitule: (value, row) => value || row.client_code || '',
  };

  const actions = (row: FactureWithReglement) => {
    const handleStatus =
      row.statut !== 2 && row.statut !== 3 && row.statut !== 4
        ? async () => {
            await dispatch(selectFactureAsync(row)).unwrap();
            setOpenStatus(true);
          }
        : undefined;

    return (
      <>
        <button
          onClick={() => openPDF(row)}
          className="p-2 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg text-gray-500"
          title="Voir"
        >
          <Eye className="w-4 h-4" />
        </button>
        <button
          onClick={() => handleAction('download', row)}
          className="p-2 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg text-gray-500"
          title="Télécharger"
        >
          <Download className="w-4 h-4" />
        </button>
        <DropdownMenuTable
          row={row}
          onStatus={handleStatus}
          onEdit={async () => {
            const rep = (await dispatch(selectFactureAsync(row)).unwrap()) as Facture;
            handleEdit(rep);
          }}
          onDownload={() => openPDF(row)}
        />
      </>
    );
  };

  // ============================================
  // Conversion pour le modal de paiement
  // ============================================

  const selectedFacturesForModal = useMemo((): Facture[] => {
    return selectedFactures.map(f => ({
      ...f,
      total_ttc_calcule: f.reste_a_regler,
    }));
  }, [selectedFactures]);

  return (
    <>
      <Helmet>
        <title>Factures - Dataven</title>
      </Helmet>

      <div className="space-y-6">
        <KPIBar kpis={kpis} period={period} loading={statusFacture} onRefresh={refresh} />

        <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
          <div className="flex items-center gap-4">
            <div>
              <div className="flex items-center gap-3">
                <h1 className="text-2xl font-bold text-gray-900 dark:text-white">Factures</h1>
                {activeFilter !== 'all' && (
                  <button
                    onClick={() => setActiveFilter('all')}
                    className={cn(
                      'inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-medium transition-colors',
                      'bg-[#007E45]/10 text-[#007E45] hover:bg-[#007E45]/20'
                    )}
                  >
                    {activeFilterLabel}
                    <X className="w-3 h-3" />
                  </button>
                )}
              </div>
              <p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
                {filteredFactures.length} facture{filteredFactures.length > 1 ? 's' : ''}
                {activeFilter !== 'all' && ` (${activeFilterLabel.toLowerCase()})`}
              </p>
            </div>
            <PeriodSelector value={period} onChange={setPeriod} />
          </div>

          <div className="flex gap-3 flex-wrap items-center">
            <ColumnSelector columns={columnConfig} onChange={setColumnConfig} />
            <ExportDropdown
              data={filteredFactures}
              columns={columnConfig}
              columnFormatters={columnFormatters}
              filename="Facture"
            />
            <AdvancedFilters
              filters={filterDefinitions}
              activeFilters={activeFilters}
              onFilterChange={(key, values) => {
                setActiveFilters(prev => ({
                  ...prev,
                  [key]: values,
                }));
              }}
              onReset={() => setActiveFilters({})}
            />

            {selectedInvoiceIds.length > 0 && (
              <div className="flex items-center gap-2">
                {selectedClient && (
                  <span className="text-xs text-gray-500 bg-gray-100 dark:bg-gray-800 px-2 py-1 rounded">
                    {selectedClient.intitule}
                  </span>
                )}
                <PrimaryButton_v2
                  onClick={handlePayment}
                  className="bg-[#338660] hover:bg-[#2A6F4F] shadow-lg shadow-green-900/20 animate-in fade-in zoom-in duration-200"
                >
                  <Wallet className="w-4 h-4 mr-2" />
                  Régler ({selectedInvoiceIds.length}) · {formatCurrency(totalSelectedBalance)}
                </PrimaryButton_v2>
              </div>
            )}

            <PrimaryButton_v2 icon={Plus} onClick={handleCreate}>
              Nouvelle facture
            </PrimaryButton_v2>
          </div>
        </div>

        {selectedClientCode && (
          <div className="flex items-center gap-2 p-3 bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300 text-sm rounded-lg border border-blue-100 dark:border-blue-900/50">
            <Info className="w-4 h-4 flex-shrink-0" />
            <span>
              Sélection limitée au client <strong>{selectedClient?.intitule}</strong>.
              <button onClick={() => setSelectedInvoiceIds([])} className="ml-2 underline hover:no-underline">
                Réinitialiser
              </button>
            </span>
          </div>
        )}

        <DataTable
          columns={visibleColumns}
          data={filteredFactures}
          actions={actions}
          status={isLoading}
          selectable={true}
          selectableFactures={selectableFactures}
          selectedIds={selectedInvoiceIds}
          onSelectRow={handleSelectInvoice}
          onSelectAll={handleSelectAll}
          onRowClick={async (row: Facture) => {
            await dispatch(selectFactureAsync(row)).unwrap();
            navigate(`/home/factures/${row.numero}`);
          }}
        />
      </div>

      <ModalStatus open={openStatus} onClose={() => setOpenStatus(false)} type_doc={SageDocumentType.FACTURE} />

      <ModalFacture
        open={isCreateModalOpen}
        onClose={() => setIsCreateModalOpen(false)}
        title={editing ? `Mettre à jour la facture ${editing.numero}` : 'Créer une facture'}
        editing={editing}
      />

      <FormModal
        isOpen={isValidationDialogOpen}
        onClose={() => setIsValidationDialogOpen(false)}
        title="Valider la facture"
      >
        <div className="p-6 space-y-4">
          <ModalValidationWarningCard
            icon={AlertTriangle}
            title="Validation automatique"
            description="En procédant au règlement, les factures sélectionnées seront automatiquement validées. Cette action est irréversible."
            onClick={handleConfirmValidationAndPayment}
          />
        </div>
      </FormModal>

      <ModalPaymentPanel
        isOpen={isPaymentPanelOpen}
        onClose={() => setIsPaymentPanelOpen(false)}
        selectedInvoices={selectedFacturesForModal}
        totalAmount={totalSelectedBalance}
      />

      {isSaving && <ModalLoading />}

      <PDFPreview open={showPreview} onClose={closePreview} data={pdfData} entreprise={CompanyInfo} />
    </>
  );
};

export default InvoicesPage;