"use client";

import { useEffect, useMemo, useState, useRef } from "react";
import { supabase } from "@/lib/supabaseClient";
import { RefreshCw, Check, X, Bell, Trash2, Plus, Edit2, ChevronDown, ChevronUp } from "lucide-react";
import { toast } from "sonner";
import BulkNotifyModal from "./cotisations/BulkNotifyModal";
import { useStaffOrgSelection } from "@/hooks/useStaffOrgSelection";

// Utility function to format dates as DD/MM/YYYY
function formatDate(dateString: string | null | undefined): string {
  if (!dateString) return "—";
  try {
    const date = new Date(dateString);
    return date.toLocaleDateString('fr-FR', {
      day: '2-digit',
      month: '2-digit',
      year: 'numeric'
    });
  } catch {
    return "—";
  }
}

// Utility function to format currency
function formatCurrency(value: number | null | undefined): string {
  if (value === null || value === undefined) return "—";
  return new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' }).format(value);
}

// Liste des caisses (colonnes du tableau)
const FUNDS = [
  { key: "URSSAF", label: "URSSAF" },
  { key: "PE_SPECTACLE", label: "FT Spectacle" },
  { key: "AUDIENS_RETRAITE", label: "Audiens Ret." },
  { key: "AUDIENS_PREVOYANCE", label: "Audiens Prév." },
  { key: "CONGES_SPECTACLES", label: "Congés Spect." },
  { key: "PREVOYANCE_RG", label: "Prévoyance RG" },
  { key: "MUTUELLE_RG", label: "Mutuelle RG" },
  { key: "PAS", label: "PAS" },
];

type Cotisation = {
  id: string;
  org_id: string;
  fund: string;
  contrib_type: string | null;
  reference: string | null;
  period_label: string;
  due_date: string | null;
  paid_date: string | null;
  status: string;
  amount_due: number;
  amount_paid: number | null;
  amount_diff: number | null;
  notes: string | null;
  created_at: string;
};

type Organization = {
  id: string;
  name: string;
  code_employeur?: string | null;
};

type PeriodRow = {
  org_id: string;
  org_name: string;
  org_code: string | null;
  period_label: string;
  due_date: string | null;
  status: string;
  funds: {
    [fundName: string]: {
      id: string;
      amount_due: number;
      amount_paid: number | null;
      amount_diff: number | null;
      paid_date: string | null;
      notes: string | null;
    };
  };
  total_due: number;
  total_paid: number;
  is_notified?: boolean;
  notification_date?: string | null;
};

type NotificationInfo = {
  id: string;
  org_id: string;
  period_label: string;
  notified_at: string;
  notified_by: string;
  email_sent_to: string;
  email_cc: string | null;
};

type CotisationsGridProps = {
  initialCotisations: Cotisation[];
  organizations: Organization[];
  notifications: NotificationInfo[];
  onEditCell: (cellData: any) => void;
  onEditPeriod: (period: PeriodRow) => void;
  onNotifyPeriod: (period: PeriodRow) => void;
  onDeletePeriod: (period: PeriodRow) => void;
  onCreatePeriod: () => void;
};

export default function CotisationsGrid({
  initialCotisations,
  organizations,
  notifications,
  onEditCell,
  onEditPeriod,
  onNotifyPeriod,
  onDeletePeriod,
  onCreatePeriod,
}: CotisationsGridProps) {
  const [cotisations, setCotisations] = useState<Cotisation[]>(initialCotisations || []);
  const [loading, setLoading] = useState(false);

  // Key for localStorage
  const FILTERS_STORAGE_KEY = 'staff-cotisations-filters';

  // Helper functions for localStorage
  const saveFiltersToStorage = (filters: any) => {
    try {
      localStorage.setItem(FILTERS_STORAGE_KEY, JSON.stringify(filters));
    } catch (error) {
      console.warn('Failed to save filters to localStorage:', error);
    }
  };

  const loadFiltersFromStorage = () => {
    try {
      const saved = localStorage.getItem(FILTERS_STORAGE_KEY);
      return saved ? JSON.parse(saved) : null;
    } catch (error) {
      console.warn('Failed to load filters from localStorage:', error);
      return null;
    }
  };

  // Load saved filters or use defaults
  const savedFilters = loadFiltersFromStorage();

  // Zustand store pour la sélection d'organisation
  const { selectedOrgId, setSelectedOrg } = useStaffOrgSelection();

  // Synchroniser le filtre local avec le store global quand selectedOrgId change
  useEffect(() => {
    setOrgFilter(selectedOrgId);
  }, [selectedOrgId]);

  // Filters state
  const [q, setQ] = useState(savedFilters?.q || "");
  const [orgFilter, setOrgFilter] = useState<string | null>(savedFilters?.orgFilter || selectedOrgId); // Initialiser avec la sélection globale
  const [statusFilter, setStatusFilter] = useState<string | null>(savedFilters?.statusFilter || null);
  const [yearFilter, setYearFilter] = useState<string | null>(savedFilters?.yearFilter || null);
  const [monthFilter, setMonthFilter] = useState<string | null>(savedFilters?.monthFilter || null);
  const [sortField, setSortField] = useState<string>(savedFilters?.sortField || "due_date");
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>(savedFilters?.sortOrder || 'desc');
  const [showFilters, setShowFilters] = useState(savedFilters?.showFilters || false);

  // Selection state
  const [selectedPeriodKeys, setSelectedPeriodKeys] = useState<Set<string>>(new Set());
  
  // Modal states
  const [showBulkNotifyModal, setShowBulkNotifyModal] = useState(false);

  // Save filters to localStorage whenever they change
  useEffect(() => {
    const filters = {
      q,
      orgFilter,
      statusFilter,
      yearFilter,
      monthFilter,
      sortField,
      sortOrder,
      showFilters
    };
    saveFiltersToStorage(filters);
  }, [q, orgFilter, statusFilter, yearFilter, monthFilter, sortField, sortOrder, showFilters]);

  // Update cotisations when props change
  useEffect(() => {
    setCotisations(initialCotisations || []);
  }, [initialCotisations]);

  // Realtime subscription for cotisations
  useEffect(() => {
    let channel: any = null;
    let mounted = true;

    (async () => {
      try {
        channel = supabase.channel("public:monthly_contributions");
        channel.on(
          "postgres_changes",
          { event: "*", schema: "public", table: "monthly_contributions" },
          (payload: any) => {
            try {
              const event = payload.event || payload.eventType || payload.type;
              const record = payload.new ?? payload.record ?? payload.payload ?? payload;

              if (event === "INSERT") {
                const newRec = record as Cotisation;
                setCotisations((rs) => {
                  if (rs.find((r) => r.id === newRec.id)) return rs;
                  return [newRec, ...rs];
                });
              } else if (event === "UPDATE") {
                setCotisations((rs) => rs.map((r) => (r.id === record.id ? { ...r, ...(record as Cotisation) } : r)));
              } else if (event === "DELETE") {
                const id = record?.id ?? payload.old?.id;
                if (id) setCotisations((rs) => rs.filter((r) => r.id !== id));
              }
            } catch (err) {
              console.error("Realtime handler error", err);
            }
          }
        );

        const sub = await channel.subscribe();
        if (!mounted) return;
        if (sub && (sub.status === "timed_out" || sub.status === "closed" || sub?.error)) {
          console.warn("Realtime subscribe returned unexpected status", sub);
        }
      } catch (err: any) {
        console.warn("Realtime subscription failed for monthly_contributions — falling back to polling.", err?.message ?? err);
      }
    })();

    return () => {
      mounted = false;
      try {
        if (channel) {
          // @ts-ignore
          if (supabase.removeChannel) supabase.removeChannel(channel);
          else channel.unsubscribe && channel.unsubscribe();
        }
      } catch (err) {
        console.warn("Error unsubscribing realtime channel", err);
      }
    };
  }, []);

  // Transform data into period rows
  const periodRows = useMemo(() => {
    const orgMap = new Map(organizations.map(org => [org.id, { name: org.name, code: org.code_employeur }]));
    const notifMap = new Map(notifications.map(n => [`${n.org_id}|${n.period_label}`, n]));

    // Group by org_id + period_label
    const grouped = new Map<string, PeriodRow>();

    cotisations.forEach((cotisation) => {
      // Ignorer les lignes "TOTAL"
      if (cotisation.fund === "TOTAL") return;

      const key = `${cotisation.org_id}|${cotisation.period_label}`;

      if (!grouped.has(key)) {
        const notificationInfo = notifMap.get(key);
        const orgInfo = orgMap.get(cotisation.org_id);
        grouped.set(key, {
          org_id: cotisation.org_id,
          org_name: orgInfo?.name || cotisation.org_id,
          org_code: orgInfo?.code || null,
          period_label: cotisation.period_label,
          due_date: cotisation.due_date,
          status: cotisation.status,
          funds: {},
          total_due: 0,
          total_paid: 0,
          is_notified: !!notificationInfo,
          notification_date: notificationInfo?.notified_at || null,
        });
      }

      const row = grouped.get(key)!;
      row.funds[cotisation.fund] = {
        id: cotisation.id,
        amount_due: cotisation.amount_due,
        amount_paid: cotisation.amount_paid,
        amount_diff: cotisation.amount_diff,
        paid_date: cotisation.paid_date,
        notes: cotisation.notes,
      };

      row.total_due += cotisation.amount_due;
      row.total_paid += cotisation.amount_paid || 0;
    });

    return Array.from(grouped.values());
  }, [cotisations, organizations, notifications]);

  // Apply filters
  const filteredRows = useMemo(() => {
    let rows = [...periodRows];

    // Text search
    if (q) {
      const qLower = q.toLowerCase();
      rows = rows.filter(row =>
        row.org_name.toLowerCase().includes(qLower) ||
        row.period_label.toLowerCase().includes(qLower)
      );
    }

    // Organization filter
    if (orgFilter) {
      rows = rows.filter(row => row.org_id === orgFilter);
    }

    // Status filter
    if (statusFilter) {
      rows = rows.filter(row => row.status === statusFilter);
    }

    // Year filter
    if (yearFilter) {
      rows = rows.filter(row => row.period_label.includes(yearFilter));
    }

    // Month filter
    if (monthFilter) {
      rows = rows.filter(row => {
        const monthNames = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"];
        const monthAbbr = ["Jan", "Fév", "Mars", "Avr", "Mai", "Juin", "Juil", "Août", "Sept", "Oct", "Nov", "Déc"];
        const monthIndex = parseInt(monthFilter) - 1;
        const monthName = monthNames[monthIndex];
        const monthShort = monthAbbr[monthIndex];
        
        return row.period_label.toLowerCase().includes(monthName.toLowerCase()) ||
               row.period_label.includes(monthShort);
      });
    }

    return rows;
  }, [periodRows, q, orgFilter, statusFilter, yearFilter, monthFilter]);

  // Apply sorting
  const sortedRows = useMemo(() => {
    const rows = [...filteredRows];

    rows.sort((a, b) => {
      let valueA: any;
      let valueB: any;

      switch (sortField) {
        case 'org_name':
          valueA = a.org_name.toLowerCase();
          valueB = b.org_name.toLowerCase();
          break;
        case 'period_label':
          valueA = a.period_label.toLowerCase();
          valueB = b.period_label.toLowerCase();
          break;
        case 'due_date':
          valueA = a.due_date ? new Date(a.due_date) : new Date(0);
          valueB = b.due_date ? new Date(b.due_date) : new Date(0);
          break;
        case 'status':
          valueA = a.status.toLowerCase();
          valueB = b.status.toLowerCase();
          break;
        case 'total_due':
          valueA = a.total_due;
          valueB = b.total_due;
          break;
        case 'total_paid':
          valueA = a.total_paid;
          valueB = b.total_paid;
          break;
        default:
          valueA = '';
          valueB = '';
      }

      if (valueA < valueB) return sortOrder === 'asc' ? -1 : 1;
      if (valueA > valueB) return sortOrder === 'asc' ? 1 : -1;
      return 0;
    });

    return rows;
  }, [filteredRows, sortField, sortOrder]);

  // Selection helpers
  const isAllSelected = sortedRows.length > 0 && selectedPeriodKeys.size === sortedRows.length;
  const isPartiallySelected = selectedPeriodKeys.size > 0 && selectedPeriodKeys.size < sortedRows.length;

  const toggleSelectAll = () => {
    if (isAllSelected) {
      setSelectedPeriodKeys(new Set());
    } else {
      setSelectedPeriodKeys(new Set(sortedRows.map(r => `${r.org_id}|${r.period_label}`)));
    }
  };

  const toggleSelectPeriod = (periodKey: string) => {
    setSelectedPeriodKeys(prev => {
      const newSet = new Set(prev);
      if (newSet.has(periodKey)) {
        newSet.delete(periodKey);
      } else {
        newSet.add(periodKey);
      }
      return newSet;
    });
  };

  // Reset selection when data changes
  useEffect(() => {
    setSelectedPeriodKeys(new Set());
  }, [sortedRows]);

  // Sorting handler
  const handleSort = (field: string) => {
    if (sortField === field) {
      setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');
    } else {
      setSortField(field);
      setSortOrder('asc');
    }
  };

  // Get sort icon
  const getSortIcon = (field: string) => {
    if (sortField !== field) return null;
    return sortOrder === 'asc' ? <ChevronUp className="w-3 h-3 inline ml-1" /> : <ChevronDown className="w-3 h-3 inline ml-1" />;
  };

  // Get unique years from period labels
  const availableYears = useMemo(() => {
    const years = new Set<string>();
    periodRows.forEach(row => {
      const match = row.period_label.match(/\d{4}/);
      if (match) years.add(match[0]);
    });
    return Array.from(years).sort((a, b) => parseInt(b) - parseInt(a));
  }, [periodRows]);

  // Get unique months from period labels
  const availableMonths = useMemo(() => {
    const monthNames = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"];
    const monthAbbr = ["Jan", "Fév", "Mars", "Avr", "Mai", "Juin", "Juil", "Août", "Sept", "Oct", "Nov", "Déc"];
    const months = new Set<number>();
    
    periodRows.forEach(row => {
      const labelLower = row.period_label.toLowerCase();
      monthNames.forEach((name, index) => {
        if (labelLower.includes(name.toLowerCase()) || row.period_label.includes(monthAbbr[index])) {
          months.add(index + 1);
        }
      });
    });
    
    return Array.from(months).sort((a, b) => a - b);
  }, [periodRows]);

  // Get unique statuses
  const availableStatuses = useMemo(() => {
    const statuses = new Set<string>();
    periodRows.forEach(row => {
      if (row.status) statuses.add(row.status);
    });
    return Array.from(statuses).sort();
  }, [periodRows]);

  // Handle refresh
  const handleRefresh = () => {
    setLoading(true);
    window.location.reload();
  };

  // Handle reset filters
  const handleResetFilters = () => {
    setQ('');
    setOrgFilter(null);
    setStatusFilter(null);
    setYearFilter(null);
    setMonthFilter(null);
    setSortField('due_date');
    setSortOrder('desc');
  };

  // Bulk actions
  const selectedPeriods = sortedRows.filter(row => selectedPeriodKeys.has(`${row.org_id}|${row.period_label}`));

  const handleBulkNotify = () => {
    if (selectedPeriods.length === 0) {
      toast.error("Aucune période sélectionnée");
      return;
    }
    setShowBulkNotifyModal(true);
  };

  const handleBulkDelete = () => {
    if (selectedPeriods.length === 0) {
      toast.error("Aucune période sélectionnée");
      return;
    }
    toast.info("Suppression groupée non implémentée pour le moment");
    // TODO: Implémenter la suppression groupée
  };

  const handleConfirmBulkNotify = async (periodIds: string[]) => {
    // Envoyer les notifications pour chaque période
    const promises = periodIds.map(async (firstFundId) => {
      try {
        const res = await fetch(`/api/staff/cotisations/${firstFundId}/notify-client`, {
          method: 'POST',
        });
        
        if (!res.ok) {
          const error = await res.json();
          throw new Error(error.error || "Erreur lors de l'envoi");
        }
        
        return { success: true, id: firstFundId };
      } catch (error) {
        console.error(`Erreur pour ${firstFundId}:`, error);
        return { success: false, id: firstFundId, error };
      }
    });

    const results = await Promise.all(promises);
    const successCount = results.filter(r => r.success).length;
    const errorCount = results.filter(r => !r.success).length;

    if (successCount > 0) {
      toast.success(`${successCount} notification${successCount > 1 ? 's envoyées' : ' envoyée'} avec succès`);
    }
    if (errorCount > 0) {
      toast.error(`${errorCount} notification${errorCount > 1 ? 's' : ''} en erreur`);
    }

    // Désélectionner les périodes
    setSelectedPeriodKeys(new Set());
  };

  return (
    <div className="relative">
      {/* Filters */}
      <div className="mb-3">
        {/* Top row: search + filter buttons */}
        <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 mb-3">
          <div className="flex-1">
            <input
              value={q}
              onChange={(e) => setQ(e.target.value)}
              placeholder="Recherche (organisation, période)"
              className="w-full rounded border px-3 py-2 text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent"
            />
          </div>
          <div className="flex items-center gap-2 flex-wrap">
            {/* Quick filters always visible */}
            <select
              value={orgFilter ?? ""}
              onChange={(e) => {
                const value = e.target.value || null;
                setOrgFilter(value);
                // Synchroniser avec le store global
                if (value) {
                  const org = organizations.find(o => o.id === value);
                  setSelectedOrg(value, org?.name || null);
                } else {
                  setSelectedOrg(null, null);
                }
              }}
              className="rounded border px-3 py-2 text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent"
            >
              <option value="">Toutes organisations</option>
              {organizations.map((org) => (
                <option key={org.id} value={org.id}>{org.name}</option>
              ))}
            </select>

            <button
              onClick={() => setShowFilters(!showFilters)}
              className="inline-flex items-center gap-1 text-sm text-blue-600 hover:text-blue-800 px-3 py-2 rounded border hover:bg-blue-50 transition"
            >
              {showFilters ? "Masquer" : "Plus de"} filtres
            </button>

            <button
              onClick={handleRefresh}
              disabled={loading}
              className="inline-flex items-center gap-1 text-sm text-emerald-600 hover:text-emerald-800 px-3 py-2 rounded border hover:bg-emerald-50 disabled:opacity-50 disabled:cursor-not-allowed transition"
              title="Actualiser les données"
            >
              <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />
              Actualiser
            </button>

            <button
              className="rounded border px-3 py-2 text-sm hover:bg-slate-50 transition"
              onClick={handleResetFilters}
            >
              Réinitialiser
            </button>

            <button
              onClick={onCreatePeriod}
              className="inline-flex items-center gap-1 px-3 py-2 bg-gradient-to-r from-purple-600 to-blue-600 text-white rounded hover:from-purple-700 hover:to-blue-700 text-sm transition"
            >
              <Plus className="w-4 h-4" />
              Nouvelle période
            </button>
          </div>
        </div>

        {/* Additional filters row (collapsible) */}
        {showFilters && (
          <div className="grid grid-cols-1 sm:grid-cols-4 gap-3 p-3 bg-slate-50 rounded border">
            <div>
              <label className="block text-xs font-medium text-slate-700 mb-1">Statut</label>
              <select
                value={statusFilter ?? ""}
                onChange={(e) => setStatusFilter(e.target.value || null)}
                className="w-full rounded border px-3 py-2 text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent"
              >
                <option value="">Tous statuts</option>
                {availableStatuses.map((status) => (
                  <option key={status} value={status}>{status}</option>
                ))}
              </select>
            </div>

            <div>
              <label className="block text-xs font-medium text-slate-700 mb-1">Mois</label>
              <select
                value={monthFilter ?? ""}
                onChange={(e) => setMonthFilter(e.target.value || null)}
                className="w-full rounded border px-3 py-2 text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent"
              >
                <option value="">Tous les mois</option>
                {availableMonths.map((month) => (
                  <option key={month} value={month}>
                    {["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"][month - 1]}
                  </option>
                ))}
              </select>
            </div>

            <div>
              <label className="block text-xs font-medium text-slate-700 mb-1">Année</label>
              <select
                value={yearFilter ?? ""}
                onChange={(e) => setYearFilter(e.target.value || null)}
                className="w-full rounded border px-3 py-2 text-sm focus:ring-2 focus:ring-purple-500 focus:border-transparent"
              >
                <option value="">Toutes années</option>
                {availableYears.map((year) => (
                  <option key={year} value={year}>{year}</option>
                ))}
              </select>
            </div>

            <div className="flex items-end">
              <div className="text-sm text-slate-600">
                {filteredRows.length} période{filteredRows.length > 1 ? 's' : ''} trouvée{filteredRows.length > 1 ? 's' : ''}
              </div>
            </div>
          </div>
        )}
      </div>

      {/* Bulk actions bar */}
      {selectedPeriodKeys.size > 0 && (
        <div className="mb-3 p-3 bg-purple-50 border border-purple-200 rounded flex items-center justify-between">
          <div className="text-sm font-medium text-purple-900">
            {selectedPeriodKeys.size} période{selectedPeriodKeys.size > 1 ? 's' : ''} sélectionnée{selectedPeriodKeys.size > 1 ? 's' : ''}
          </div>
          <div className="flex items-center gap-2">
            <button
              onClick={handleBulkNotify}
              className="inline-flex items-center gap-1 px-3 py-1.5 bg-amber-500 text-white rounded hover:bg-amber-600 text-sm transition"
            >
              <Bell className="w-4 h-4" />
              Notifier
            </button>
            <button
              onClick={handleBulkDelete}
              className="inline-flex items-center gap-1 px-3 py-1.5 bg-red-500 text-white rounded hover:bg-red-600 text-sm transition"
            >
              <Trash2 className="w-4 h-4" />
              Supprimer
            </button>
            <button
              onClick={() => setSelectedPeriodKeys(new Set())}
              className="inline-flex items-center gap-1 px-3 py-1.5 bg-slate-200 text-slate-700 rounded hover:bg-slate-300 text-sm transition"
            >
              <X className="w-4 h-4" />
              Annuler
            </button>
          </div>
        </div>
      )}

      {/* Table */}
      <div className="rounded-lg border bg-white overflow-hidden">
        <div className="overflow-x-auto">
          {sortedRows.length === 0 ? (
            <div className="py-12 text-center text-slate-500">
              Aucune cotisation trouvée
            </div>
          ) : (
            <table className="w-full text-xs">
              <thead>
                <tr className="border-b bg-slate-50">
                  <th className="px-2 py-2 text-left">
                    <input
                      type="checkbox"
                      checked={isAllSelected}
                      ref={(input) => {
                        if (input) input.indeterminate = isPartiallySelected;
                      }}
                      onChange={toggleSelectAll}
                      className="rounded border-slate-300"
                    />
                  </th>
                  <th
                    className="text-left font-medium px-2 py-2 cursor-pointer hover:bg-slate-100 transition"
                    onClick={() => handleSort('org_name')}
                  >
                    Code {getSortIcon('org_name')}
                  </th>
                  <th
                    className="text-left font-medium px-2 py-2 cursor-pointer hover:bg-slate-100 transition"
                    onClick={() => handleSort('period_label')}
                  >
                    Période {getSortIcon('period_label')}
                  </th>
                  <th
                    className="text-left font-medium px-2 py-2 cursor-pointer hover:bg-slate-100 transition"
                    onClick={() => handleSort('due_date')}
                  >
                    Échéance {getSortIcon('due_date')}
                  </th>
                  <th
                    className="text-left font-medium px-2 py-2 cursor-pointer hover:bg-slate-100 transition"
                    onClick={() => handleSort('status')}
                  >
                    Statut {getSortIcon('status')}
                  </th>
                  {FUNDS.map((fundObj) => (
                    <th key={fundObj.key} className="text-right font-medium px-2 py-2 whitespace-nowrap">
                      {fundObj.label}
                    </th>
                  ))}
                  <th
                    className="text-right font-medium px-2 py-2 bg-slate-100 cursor-pointer hover:bg-slate-200 transition"
                    onClick={() => handleSort('total_due')}
                  >
                    Total {getSortIcon('total_due')}
                  </th>
                  <th className="text-center font-medium px-2 py-2">Actions</th>
                </tr>
              </thead>
              <tbody>
                {sortedRows.map((row) => {
                  const periodKey = `${row.org_id}|${row.period_label}`;
                  const isSelected = selectedPeriodKeys.has(periodKey);

                  return (
                    <tr
                      key={periodKey}
                      className={`border-b hover:bg-slate-50 transition ${isSelected ? 'bg-purple-50' : ''}`}
                    >
                      <td className="px-2 py-2">
                        <input
                          type="checkbox"
                          checked={isSelected}
                          onChange={() => toggleSelectPeriod(periodKey)}
                          className="rounded border-slate-300"
                        />
                      </td>
                      <td className="px-2 py-2 font-medium text-slate-900" title={row.org_name}>
                        {row.org_code || row.org_name}
                      </td>
                      <td className="px-2 py-2">
                        <div className="flex items-center gap-1">
                          <span className="text-slate-900">{row.period_label}</span>
                          {row.is_notified && (
                            <span
                              className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded-full text-xs font-medium bg-amber-100 text-amber-700"
                              title={`Notifié le ${formatDate(row.notification_date)}`}
                            >
                              <Bell className="w-3 h-3" />
                            </span>
                          )}
                        </div>
                      </td>
                      <td className="px-2 py-2 text-slate-600 whitespace-nowrap">
                        {formatDate(row.due_date)}
                      </td>
                      <td className="px-2 py-2">
                        <span
                          className={`inline-flex items-center gap-1 px-1.5 py-0.5 rounded-full text-xs font-medium whitespace-nowrap ${
                            row.status === "Fait"
                              ? "bg-emerald-100 text-emerald-700"
                              : row.status === "En retard"
                              ? "bg-red-100 text-red-700"
                              : "bg-amber-100 text-amber-700"
                          }`}
                        >
                          {row.status === "Fait" && <Check className="w-3 h-3" />}
                          {row.status === "En retard" && <X className="w-3 h-3" />}
                          {row.status}
                        </span>
                      </td>
                      {FUNDS.map((fundObj) => {
                        const fundData = row.funds[fundObj.key];
                        return (
                          <td
                            key={fundObj.key}
                            className="px-2 py-2 text-right cursor-pointer hover:bg-purple-50 transition"
                            onClick={() => {
                              if (fundData) {
                                onEditCell({
                                  id: fundData.id,
                                  org_id: row.org_id,
                                  org_name: row.org_name,
                                  period_label: row.period_label,
                                  fund: fundObj.key,
                                  amount_due: fundData.amount_due,
                                  amount_paid: fundData.amount_paid,
                                  amount_diff: fundData.amount_diff,
                                  paid_date: fundData.paid_date,
                                  due_date: row.due_date,
                                  status: row.status,
                                  notes: fundData.notes,
                                });
                              }
                            }}
                          >
                            {fundData ? (
                              <div className="flex flex-col items-end">
                                <span className="font-medium text-slate-900 whitespace-nowrap">
                                  {formatCurrency(fundData.amount_due)}
                                </span>
                                {fundData.amount_paid !== null && (
                                  <span className="text-[10px] text-emerald-600 whitespace-nowrap">
                                    Payé: {formatCurrency(fundData.amount_paid)}
                                  </span>
                                )}
                              </div>
                            ) : (
                              <span className="text-slate-400">—</span>
                            )}
                          </td>
                        );
                      })}
                      <td className="px-2 py-2 text-right font-semibold text-slate-900 bg-slate-50">
                        <div className="flex flex-col items-end">
                          <span className="whitespace-nowrap">{formatCurrency(row.total_due)}</span>
                          {row.total_paid > 0 && (
                            <span className="text-[10px] text-emerald-600 whitespace-nowrap">
                              Payé: {formatCurrency(row.total_paid)}
                            </span>
                          )}
                        </div>
                      </td>
                      <td className="px-2 py-2">
                        <div className="flex items-center justify-center gap-2">
                          <button
                            onClick={() => onEditPeriod(row)}
                            className="p-1.5 text-blue-600 hover:bg-blue-50 rounded-lg transition"
                            title="Modifier la période"
                          >
                            <Edit2 className="w-4 h-4" />
                          </button>
                          <button
                            onClick={() => onNotifyPeriod(row)}
                            className={`p-1.5 rounded-lg hover:bg-amber-50 transition ${
                              row.is_notified ? 'text-green-600' : 'text-amber-600'
                            }`}
                            title={row.is_notified ? "Notifier à nouveau" : "Notifier le client"}
                          >
                            <Bell className="w-4 h-4" />
                          </button>
                          <button
                            onClick={() => onDeletePeriod(row)}
                            className="p-1.5 text-red-600 hover:bg-red-50 rounded-lg transition"
                            title="Supprimer la période"
                          >
                            <Trash2 className="w-4 h-4" />
                          </button>
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          )}
        </div>
      </div>

      {/* Summary */}
      <div className="mt-3 text-sm text-slate-600">
        Affichage de {sortedRows.length} période{sortedRows.length > 1 ? 's' : ''} sur {periodRows.length} au total
      </div>

      {/* Bulk Notify Modal */}
      {showBulkNotifyModal && (
        <BulkNotifyModal
          periods={selectedPeriods}
          onClose={() => setShowBulkNotifyModal(false)}
          onConfirm={handleConfirmBulkNotify}
        />
      )}
    </div>
  );
}
