// app/(app)/virements-salaires/page.tsx
"use client";
import React, { useMemo, useState, useEffect } from "react";
import { useSearchParams, usePathname, useRouter } from "next/navigation";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { Loader2, Search, Download, ExternalLink, Info, Copy, Check } from "lucide-react";
import { usePageTitle } from "@/hooks/usePageTitle";
import { useDemoMode } from "@/hooks/useDemoMode";

// --- Types ---
type PeriodKey =
  | "toute_annee"
  | "premier_semestre"
  | "second_semestre"
  | "trimestre_1"
  | "trimestre_2"
  | "trimestre_3"
  | "trimestre_4"
  | `mois_${1|2|3|4|5|6|7|8|9|10|11|12}`;

type Filters = {
  year: number;
  period: PeriodKey;
  from?: string; // YYYY-MM-DD
  to?: string;   // YYYY-MM-DD
};

type VirementItem = {
  id: string;
  periode_label?: string;
  periode?: string;
  callsheet?: string;
  num_appel?: string;
  date_mois?: string;
  date?: string;
  total_salaries_eur?: number;
  total?: number;
  virement_recu?: boolean | string;
  virement_recu_date?: string | null; // Date de réception du virement
  salaires_payes?: boolean | string;
  pdf_url?: string;
};

type OrgSummary = {
  structure_api: string | null;
  virements_salaires: string | null;
  iban: string | null;
  bic: string | null;
  gocardless?: string | null;
} | null;

// Vue client (virements gérés par le client)
type ClientVirementItem = {
  id: string;
  kind: 'CDDU_MONO' | 'CDDU_MULTI' | 'RG';
  source: 'contrat' | 'paie_multi' | 'paie_rg' | 'payslip';
  contract_id?: string;
  salarie?: string | null;
  salarie_matricule?: string | null;
  reference?: string | null;
  profession?: string | null;
  date_debut?: string | null;
  date_fin?: string | null;
  periode?: string | null; // ex: "2025-08-01" ou "08/2025"
  net_a_payer?: number | null;
  virement_effectue?: 'oui' | 'non' | 'na';
};

type ClientInfo = {
  id: string;
  name: string;
  api_name?: string;
} | null;

// --- Helpers ---
function pad2(n: number) { return String(n).padStart(2, "0"); }
function monthStartISO(y: number, m: number) { return `${y}-${pad2(m)}-01`; }
function monthEndISO(y: number, m: number) {
  const d = new Date(y, m, 0); // last day of month
  return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;
}
function quarterRange(y: number, q: 1 | 2 | 3 | 4) {
  const startMonth = (q - 1) * 3 + 1; 
  const endMonth = startMonth + 2;
  return { from: monthStartISO(y, startMonth), to: monthEndISO(y, endMonth) };
}

function formatFR(iso: string) {
  if (!iso) return "—";
  const d = new Date(iso);
  if (isNaN(d.getTime())) return "—";
  const dd = String(d.getDate()).padStart(2, '0');
  const mm = String(d.getMonth() + 1).padStart(2, '0');
  const yyyy = d.getFullYear();
  return `${dd}/${mm}/${yyyy}`;
}

function maskEndDate(iso?: string | null) {
  if (!iso) return '—';
  // Masquer la date 2099-01-01 utilisée comme fin indéterminée
  if (iso.startsWith('2099-01-01')) return '—';
  return formatFR(iso);
}

function capitalize(str: string) {
  if (!str) return str;
  return str.charAt(0).toUpperCase() + str.slice(1);
}

// 🎭 Données fictives pour le mode démo (virements gérés par Odentas)
const DEMO_VIREMENTS: VirementItem[] = [
  {
    id: 'demo-vir-001',
    periode_label: 'Septembre 2025',
    periode: '2025-09',
    callsheet: 'FDR-2025-09',
    num_appel: 'FDR-2025-09',
    date_mois: '2025-09-01',
    date: '2025-09-01',
    total_salaries_eur: 12450.50,
    total: 12450.50,
    virement_recu: true,
    virement_recu_date: '2025-09-15',
    salaires_payes: true,
  },
  {
    id: 'demo-vir-002',
    periode_label: 'Août 2025',
    periode: '2025-08',
    callsheet: 'FDR-2025-08',
    num_appel: 'FDR-2025-08',
    date_mois: '2025-08-01',
    date: '2025-08-01',
    total_salaries_eur: 15230.80,
    total: 15230.80,
    virement_recu: true,
    virement_recu_date: '2025-08-12',
    salaires_payes: true,
  },
  {
    id: 'demo-vir-003',
    periode_label: 'Juillet 2025',
    periode: '2025-07',
    callsheet: 'FDR-2025-07',
    num_appel: 'FDR-2025-07',
    date_mois: '2025-07-01',
    date: '2025-07-01',
    total_salaries_eur: 18765.25,
    total: 18765.25,
    virement_recu: true,
    virement_recu_date: '2025-07-18',
    salaires_payes: true,
  },
  {
    id: 'demo-vir-004',
    periode_label: 'Juin 2025',
    periode: '2025-06',
    callsheet: 'FDR-2025-06',
    num_appel: 'FDR-2025-06',
    date_mois: '2025-06-01',
    date: '2025-06-01',
    total_salaries_eur: 14890.00,
    total: 14890.00,
    virement_recu: true,
    virement_recu_date: '2025-06-14',
    salaires_payes: true,
  },
  {
    id: 'demo-vir-005',
    periode_label: 'Mai 2025',
    periode: '2025-05',
    callsheet: 'FDR-2025-05',
    num_appel: 'FDR-2025-05',
    date_mois: '2025-05-01',
    date: '2025-05-01',
    total_salaries_eur: 11250.75,
    total: 11250.75,
    virement_recu: true,
    virement_recu_date: '2025-05-16',
    salaires_payes: true,
  },
];

// Affiche une période au format "Mois YYYY" (ex: "Septembre 2025")
function formatPeriode(per?: string | null) {
  if (!per) return '—';
  const s = String(per).trim();
  // ISO: YYYY-MM or YYYY-MM-DD
  const mIso = s.match(/^(\d{4})-(\d{2})(?:-(\d{2}))?$/);
  if (mIso) {
    const y = parseInt(mIso[1], 10);
    const m = parseInt(mIso[2], 10);
    const d = new Date(y, (isNaN(m) ? 1 : m) - 1, 1);
    return capitalize(d.toLocaleDateString('fr-FR', { month: 'long', year: 'numeric' }));
  }
  // MM/YYYY
  const mMY = s.match(/^(\d{1,2})\/(\d{4})$/);
  if (mMY) {
    const m = parseInt(mMY[1], 10);
    const y = parseInt(mMY[2], 10);
    const d = new Date(y, (isNaN(m) ? 1 : m) - 1, 1);
    return capitalize(d.toLocaleDateString('fr-FR', { month: 'long', year: 'numeric' }));
  }
  // Fallback: essayer Date()
  const d = new Date(s);
  if (!isNaN(d.getTime())) {
    return capitalize(d.toLocaleDateString('fr-FR', { month: 'long', year: 'numeric' }));
  }
  return s;
}

function formatCurrency(amount?: number) {
  if (amount == null) return "—";
  return new Intl.NumberFormat('fr-FR', {
    style: 'currency',
    currency: 'EUR'
  }).format(amount);
}

function toBoolish(v: any): boolean | undefined {
  if (v === true) return true;
  if (v === false) return false;
  if (typeof v === 'string') {
    const s = v.trim().toLowerCase();
    if (s === 'oui' || s === 'yes' || s === 'true') return true;
    if (s === 'non' || s === 'no' || s === 'false') return false;
  }
  return undefined;
}

// --- Hook pour récupérer les infos utilisateur et les organisations (staff uniquement) ---
function useUserInfo() {
  return useQuery({
    queryKey: ["user-info"],
    queryFn: async () => {
      try {
        const res = await fetch("/api/me", { 
          cache: "no-store", 
          headers: { Accept: "application/json" },
          credentials: "include"
        });
        if (!res.ok) return null;
        const me = await res.json();
        
        return {
          isStaff: Boolean(me.is_staff || me.isStaff),
          orgId: me.orgId || me.active_org_id || null,
          orgName: me.orgName || me.active_org_name || "Organisation",
          api_name: me.active_org_api_name
        };
      } catch {
        return null;
      }
    },
    staleTime: 30_000,
  });
}

function useOrganizations() {
  const { data: userInfo, isSuccess: userInfoLoaded } = useUserInfo();
  
  const query = useQuery({
    queryKey: ["organizations"],
    queryFn: async () => {
      try {
        const res = await fetch("/api/staff/organizations", { 
          cache: "no-store", 
          headers: { Accept: "application/json" },
          credentials: "include"
        });
        if (!res.ok) return [];
        const data = await res.json();
        return data.organizations || [];
      } catch {
        return [];
      }
    },
    enabled: false,
    staleTime: 60_000,
  });

  React.useEffect(() => {
    if (userInfoLoaded && userInfo?.isStaff && !query.data && !query.isFetching) {
      query.refetch();
    }
  }, [userInfo, userInfoLoaded, query]);

  return query;
}

// --- Hook pour récupérer les virements ---
function useVirements(filters: Filters, selectedOrgId?: string, isDemoMode: boolean = false) {
  // Récupération dynamique des infos utilisateur via /api/me
  const { data: userInfo } = useUserInfo();

  const qs = new URLSearchParams();
  qs.set("year", String(filters.year));
  qs.set("period", filters.period);
  if (filters.from) qs.set("from", filters.from);
  if (filters.to) qs.set("to", filters.to);
  
  // Si c'est un staff qui a sélectionné une organisation spécifique
  if (selectedOrgId && userInfo?.isStaff) {
    qs.set("org_id", selectedOrgId);
  }

  return useQuery<{ items: VirementItem[]; enabled?: boolean; org?: OrgSummary; client?: { unpaid: ClientVirementItem[]; recent: ClientVirementItem[] } }>({
    queryKey: ["virements-salaires", filters.year, userInfo?.orgId, selectedOrgId, isDemoMode],
    queryFn: async () => {
      // 🎭 En mode démo, retourner les données fictives
      if (isDemoMode) {
        console.log('🎭 [VIREMENTS] Mode démo - retour de données fictives');
        return {
          items: DEMO_VIREMENTS,
          enabled: true, // Mode Odentas activé en démo
          org: {
            structure_api: 'demo-org',
            virements_salaires: 'odentas',
            iban: 'FR76 1234 5678 9012 3456 7890 123',
            bic: 'ABCDEFGH',
          } as OrgSummary,
          client: undefined,
        };
      }
      
      // On récupère toutes les données de l'année, le filtrage par période se fera côté client
      const simpleQs = new URLSearchParams();
      simpleQs.set("year", String(filters.year));
      simpleQs.set("period", "toute_annee");
      
      // Si c'est un staff qui a sélectionné une organisation spécifique
      if (selectedOrgId && userInfo?.isStaff) {
        simpleQs.set("org_id", selectedOrgId);
      }
      
      const res = await fetch(`/api/virements-salaires?${simpleQs.toString()}`, {
        credentials: "include",
        headers: { Accept: "application/json" }
      });
      if (!res.ok) {
        const text = await res.text();
        throw new Error(text || `Erreur ${res.status}`);
      }
      const data = await res.json();
      return {
        items: (data?.items || []) as VirementItem[],
        enabled: Boolean(data?.enabled),
        org: (data?.org ?? null) as OrgSummary,
        client: data?.client as { unpaid: ClientVirementItem[]; recent: ClientVirementItem[] } | undefined,
      };
    },
    staleTime: 15_000,
    enabled: !!userInfo, // Ne pas exécuter si pas d'infos utilisateur
  });
}

export default function VirementsPage() {
  usePageTitle("Virements salaires");
  
  // 🎭 Détection du mode démo
  const { isDemoMode } = useDemoMode();
  
  const now = new Date();
  const [filters, setFilters] = useState<Filters>({ 
    year: now.getFullYear(), 
    period: "toute_annee" 
  });
  const [searchQuery, setSearchQuery] = useState("");
  const [aboutOpen, setAboutOpen] = useState(false);
  const [copiedField, setCopiedField] = useState<null | 'iban' | 'bic' | 'benef'>(null);
  const [selectedOrgId, setSelectedOrgId] = useState<string>("");

  const { data: userInfo, isLoading: isLoadingUser } = useUserInfo();
  const { data: organizations, isLoading: isLoadingOrgs, error: orgsError } = useOrganizations();
  const queryClient = useQueryClient();

  const years = useMemo(() => {
    const base = now.getFullYear();
    return Array.from({ length: 7 }, (_, i) => base - i);
  }, [now]);

  // URL sync
  const searchParams = useSearchParams();
  const pathname = usePathname();
  const router = useRouter();

  useEffect(() => {
    const sp = searchParams; 
    if (!sp) return;
    const yParam = sp.get("year");
    const pParam = sp.get("period");
    const from = sp.get("from") || undefined; 
    const to = sp.get("to") || undefined;
    const next: Filters = { ...filters };
    
    if (yParam) { 
      const y = parseInt(yParam, 10); 
      if (!isNaN(y)) next.year = y; 
    }
    
    if (pParam) {
      const allowed = new Set<PeriodKey>([
        "toute_annee", "premier_semestre", "second_semestre",
        "trimestre_1", "trimestre_2", "trimestre_3", "trimestre_4",
        "mois_1", "mois_2", "mois_3", "mois_4", "mois_5", "mois_6",
        "mois_7", "mois_8", "mois_9", "mois_10", "mois_11", "mois_12",
      ] as PeriodKey[]);
      
      if (allowed.has(pParam as PeriodKey)) {
        next.period = pParam as PeriodKey;
        if (!from && !to) {
          const y = next.year;
          if (pParam === "premier_semestre") { 
            next.from = monthStartISO(y, 1); 
            next.to = monthEndISO(y, 6); 
          }
          else if (pParam === "second_semestre") { 
            next.from = monthStartISO(y, 7); 
            next.to = monthEndISO(y, 12); 
          }
          else if (pParam === "trimestre_1") { 
            const r = quarterRange(y, 1); 
            next.from = r.from; 
            next.to = r.to; 
          }
          else if (pParam === "trimestre_2") { 
            const r = quarterRange(y, 2); 
            next.from = r.from; 
            next.to = r.to; 
          }
          else if (pParam === "trimestre_3") { 
            const r = quarterRange(y, 3); 
            next.from = r.from; 
            next.to = r.to; 
          }
          else if (pParam === "trimestre_4") { 
            const r = quarterRange(y, 4); 
            next.from = r.from; 
            next.to = r.to; 
          }
          else if (pParam.startsWith("mois_")) { 
            const m = parseInt(pParam.split("_")[1]!, 10); 
            if (!isNaN(m)) { 
              next.from = monthStartISO(y, m); 
              next.to = monthEndISO(y, m); 
            } 
          }
          else if (pParam === "toute_annee") { 
            next.from = undefined; 
            next.to = undefined; 
          }
        }
      }
    }
    
    next.from = (from as any) ?? next.from; 
    next.to = (to as any) ?? next.to;
    const changed = next.year !== filters.year || next.period !== filters.period || next.from !== filters.from || next.to !== filters.to;
    if (changed) setFilters(next);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [searchParams?.toString()]);

  useEffect(() => {
    if (!pathname) return;
    const qs = new URLSearchParams();
    qs.set("year", String(filters.year));
    qs.set("period", filters.period);
    if (filters.from) qs.set("from", filters.from);
    if (filters.to) qs.set("to", filters.to);
    router.replace(`${pathname}?${qs.toString()}`, { scroll: false });
  }, [filters, pathname, router]);

  const { data, isLoading, isError, error, isFetching } = useVirements(filters, selectedOrgId, isDemoMode);
  const loadingOrg = isLoading || isFetching || data === undefined;
  const org: OrgSummary = (data?.org ?? null) as OrgSummary;
  
  // Amélioration de la détection du mode Odentas (toujours actif en mode démo)
  const isOdentas = isDemoMode || (!loadingOrg && (
    Boolean(data?.enabled) || 
    (typeof org?.virements_salaires === 'string' && org!.virements_salaires!.toLowerCase().includes('odentas'))
  ));
  
  const gestionLabel = loadingOrg ? "Chargement…" : (isOdentas ? "Odentas" : "Votre structure");
  const items: VirementItem[] = (data?.items ?? []) as VirementItem[];
  const clientUnpaidAll: ClientVirementItem[] = (data?.client?.unpaid ?? []) as ClientVirementItem[];
  const clientRecentAll: ClientVirementItem[] = (data?.client?.recent ?? []) as ClientVirementItem[];

  const clientFilter = (arr: ClientVirementItem[]) => {
    if (!searchQuery.trim()) return arr;
    const q = searchQuery.toLowerCase();
    return arr.filter(it =>
      (it.salarie || '').toLowerCase().includes(q) ||
      (it.reference || '').toLowerCase().includes(q) ||
      (it.profession || '').toLowerCase().includes(q) ||
      (it.periode || '').toLowerCase().includes(q)
    );
  };
  const clientUnpaid = clientFilter(clientUnpaidAll);
  const clientRecent = clientFilter(clientRecentAll);

  // Mutation: marquer un payslip comme viré
  async function markPayslipDone(payslipId: string) {
    try {
      // Optimistic UI: masquer l'élément avant refetch
      // (on ne modifie pas le cache TanStack ici, on refetch directement après)
      await fetch(`/api/payslips/${payslipId}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
        credentials: 'include',
        body: JSON.stringify({ transfer_done: true })
      });
      // Invalider les requêtes liées pour recharger la liste
      queryClient.invalidateQueries({ queryKey: ["virements-salaires"] });
    } catch (e) {
      console.error('Erreur marquage payslip:', e);
      alert('Erreur lors du marquage du virement.');
    }
  }

  // Filtrage local pour la recherche ET la période
  const filteredItems = useMemo((): VirementItem[] => {
    let result: VirementItem[] = items;
    
    // 1. Filtrage par année (toujours actif)
    result = result.filter((item: VirementItem) => {
      if (!item.date_mois) return false;
      const [year] = item.date_mois.split('-').map(Number);
      return year === filters.year;
    });
    
    // 2. Filtrage par période spécifique (si pas "toute_annee")
    if (filters.period !== "toute_annee") {
      result = result.filter((item: VirementItem) => {
        if (!item.date_mois) return false;
        
        const [, month] = item.date_mois.split('-').map(Number);
        
        switch (filters.period) {
          case "premier_semestre":
            return month >= 1 && month <= 6;
          case "second_semestre":
            return month >= 7 && month <= 12;
          case "trimestre_1":
            return month >= 1 && month <= 3;
          case "trimestre_2":
            return month >= 4 && month <= 6;
          case "trimestre_3":
            return month >= 7 && month <= 9;
          case "trimestre_4":
            return month >= 10 && month <= 12;
          default:
            // Pour les mois individuels (mois_1, mois_2, etc.)
            if (filters.period.startsWith("mois_")) {
              const targetMonth = parseInt(filters.period.split("_")[1]!, 10);
              return month === targetMonth;
            }
            return true;
        }
      });
    }
    
    // 3. Filtrage par recherche textuelle
    if (searchQuery.trim()) {
      const query = searchQuery.toLowerCase();
      result = result.filter((item: VirementItem) => 
        (item.callsheet || item.num_appel || "").toLowerCase().includes(query) ||
        (item.periode_label || item.periode || "").toLowerCase().includes(query)
      );
    }
    
    return result;
  }, [items, searchQuery, filters.period, filters.year]);

  return (
    <div className="space-y-5">
      {/* En-tête + Recherche */}
      <section className="rounded-2xl border bg-white p-4">
        <div className="flex flex-col sm:flex-row sm:items-center gap-3">
          <div>
            <h1 className="text-xl font-semibold">Virements de salaires</h1>
            <p className="text-sm text-slate-600 mt-1">
              Suivez vos appels à virement, l'état des virements reçus et les salaires payés.
            </p>
          </div>
          {isOdentas && (
            <div className="sm:ml-auto flex items-center gap-2 w-full sm:w-auto">
              <div className="flex items-center gap-2 px-3 py-2 rounded-xl border w-full sm:w-80">
                <Search className="w-4 h-4" />
                <input 
                  value={searchQuery} 
                  onChange={(e) => setSearchQuery(e.target.value)} 
                  placeholder="N° appel, période…" 
                  className="bg-transparent outline-none text-sm flex-1" 
                />
              </div>
            </div>
          )}
        </div>

        {/* 🎭 Message informatif en mode démo */}
        {isDemoMode && (
          <div className="mt-4 rounded-xl border-2 border-amber-200 bg-gradient-to-r from-amber-50 to-orange-50 p-3 shadow-sm">
            <div className="flex items-center gap-3">
              <div className="rounded-lg bg-amber-100 p-2">
                <Info className="h-5 w-5 text-amber-700" />
              </div>
              <h3 className="font-semibold text-amber-900">Mode démonstration</h3>
            </div>
          </div>
        )}

        {/* Filtres de période */}
        <div className="mt-4 flex flex-col sm:flex-row sm:items-stretch gap-3">
          <div className="flex items-center gap-2">
            <label className="text-sm font-medium">Année :</label>
            <select
              className="px-3 py-2 rounded-lg border bg-white text-sm"
              value={filters.year}
              onChange={(e) => setFilters(f => ({ ...f, year: parseInt(e.target.value, 10) }))}
            >
              {years.map(y => (
                <option key={y} value={y}>{y}</option>
              ))}
            </select>
          </div>
          
          {/* Sélecteur d'organisation (visible uniquement par le staff) */}
          {userInfo?.isStaff && (
            <div className="flex items-center gap-2">
              <label className="text-sm font-medium">Organisation :</label>
              <select
                className="px-3 py-2 rounded-lg border bg-white text-sm min-w-[200px]"
                value={selectedOrgId}
                onChange={(e) => setSelectedOrgId(e.target.value)}
                disabled={!organizations || organizations.length === 0}
              >
                <option value="">
                  {!organizations || organizations.length === 0 
                    ? "Chargement..." 
                    : "Toutes les organisations"}
                </option>
                {organizations && organizations.map((org: any) => (
                  <option key={org.id} value={org.id}>{org.name}</option>
                ))}
              </select>
              {organizations && organizations.length > 0 && (
                <span className="text-xs text-slate-500">({organizations.length})</span>
              )}
            </div>
          )}
          
          {isOdentas && (
            <div className="flex items-center gap-2">
              <label className="text-sm font-medium">Période :</label>
              <select
                className="px-3 py-2 rounded-lg border bg-white text-sm"
                value={filters.period}
                onChange={(e) => setFilters(f => ({ ...f, period: e.target.value as PeriodKey }))}
              >
                <option value="toute_annee">Toute l'année</option>
                <optgroup label="Semestres">
                  <option value="premier_semestre">Premier semestre</option>
                  <option value="second_semestre">Second semestre</option>
                </optgroup>
                <optgroup label="Trimestres">
                  <option value="trimestre_1">Trimestre 1</option>
                  <option value="trimestre_2">Trimestre 2</option>
                  <option value="trimestre_3">Trimestre 3</option>
                  <option value="trimestre_4">Trimestre 4</option>
                </optgroup>
                <optgroup label="Mois">
                  {[...Array(12)].map((_, i) => (
                    <option key={i + 1} value={`mois_${i + 1}` as PeriodKey}>
                      {new Date(2023, i).toLocaleDateString('fr-FR', { month: 'long' })}
                    </option>
                  ))}
                </optgroup>
              </select>
            </div>
          )}
          <div className="sm:ml-auto min-w-[280px] max-w-sm flex-1">
            <div className="h-full rounded-xl border bg-white p-3">
              <div className="flex items-start justify-between">
                <div>
                  <div className="text-sm font-semibold">Gestion des virements</div>
                  <div className="text-xs text-slate-600">Les virements de salaires sont effectués par</div>
                </div>
                <div className="flex items-center gap-2">
                  <div className="relative group inline-block">
                    <button
                      type="button"
                      disabled
                      aria-disabled="true"
                      className="text-xs px-2 py-1 rounded-md border opacity-60 cursor-not-allowed"
                    >
                      Modifier
                    </button>
                    <div
                      role="tooltip"
                      className="pointer-events-none absolute right-0 mt-2 w-64 px-3 py-2 rounded-lg bg-slate-900 text-white text-xs shadow-lg opacity-0 group-hover:opacity-100 translate-y-1 group-hover:translate-y-0 transition"
                    >
                      Bientôt disponible, veuillez nous contacter.
                      <div className="absolute -top-1 right-6 w-2 h-2 rotate-45 bg-slate-900" />
                    </div>
                  </div>
                </div>
              </div>
              <div className="mt-3 flex items-center justify-between gap-2">
                <div className={`inline-flex items-center gap-2 px-3 py-2 rounded-lg border text-sm ${loadingOrg ? 'bg-slate-50 border-slate-200 text-slate-400' : (isOdentas ? 'bg-emerald-50 border-emerald-200 text-emerald-700' : 'bg-slate-50 border-slate-200 text-slate-700')}`}>
                  <span className="inline-block w-2 h-2 rounded-full" style={{ backgroundColor: isOdentas ? '#10b981' : '#64748b', opacity: loadingOrg ? 0.6 : 1 }} />
                  <span className="font-medium">{gestionLabel}</span>
                </div>
                <button
                  type="button"
                  onClick={() => !loadingOrg && setAboutOpen(true)}
                  disabled={loadingOrg}
                  className={`inline-flex items-center gap-1 text-xs px-2 py-1 rounded-md border transition-colors ${loadingOrg ? 'opacity-50 cursor-not-allowed' : 'hover:bg-slate-50'}`}
                  aria-label="En savoir plus sur les virements"
                >
                  <Info className="w-3.5 h-3.5" />
                  En savoir plus
                </button>
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* Tableau principal */}
      {isOdentas ? (
        <section className="rounded-2xl border bg-white">
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b bg-slate-50/80">
                  <Th>Période</Th>
                  <Th>N° d'appel</Th>
                  <Th>Date d'appel</Th>
                  <Th className="text-right">Salaires nets</Th>
                  <Th className="text-center">Virement reçu</Th>
                  <Th className="text-center">Salaires payés</Th>
                  <Th className="text-center">Document</Th>
                </tr>
              </thead>
              <tbody>
                {isLoading ? (
                  <tr>
                    <td colSpan={7} className="py-12 text-center text-slate-500">
                      <Loader2 className="w-4 h-4 inline animate-spin mr-2" /> 
                      Chargement…
                    </td>
                  </tr>
                ) : isError ? (
                  <tr>
                    <td colSpan={7} className="py-12 text-center text-rose-500">
                      Erreur : {(error as any)?.message || 'imprévue'}
                    </td>
                  </tr>
                ) : filteredItems.length === 0 ? (
                  <tr>
                    <td colSpan={7} className="py-12 text-center text-slate-500">
                      {searchQuery ? 'Aucun virement trouvé pour cette recherche.' : 'Aucun virement de salaires trouvé.'}
                    </td>
                  </tr>
                ) : (
                  filteredItems.map((row: VirementItem) => (
                    <tr key={row.id} className="border-b last:border-b-0 hover:bg-slate-50/50">
                      <Td>{row.periode_label || formatPeriode(row.periode) || "—"}</Td>
                      <Td>
                        <span className="font-medium">
                          {row.num_appel || row.callsheet || "—"}
                        </span>
                      </Td>
                      <Td>{formatFR(row.date_mois || row.date || "")}</Td>
                      <Td className="text-right font-medium">
                        {formatCurrency(row.total_salaries_eur ?? row.total)}
                      </Td>
                      <Td className="text-center">
                        <StatusBadge status={row.virement_recu} date={row.virement_recu_date} />
                      </Td>
                      <Td className="text-center">
                        <StatusBadge status={row.salaires_payes} />
                      </Td>
                      <Td className="text-center">
                        {row.pdf_url ? (
                          <a 
                            href={row.pdf_url} 
                            target="_blank" 
                            rel="noreferrer" 
                            className="inline-flex items-center gap-1 px-2 py-1 rounded-lg bg-pink-100 text-pink-700 hover:bg-pink-200 transition-colors text-xs"
                          >
                            <Download className="w-3 h-3" />
                            PDF
                            <ExternalLink className="w-3 h-3" />
                          </a>
                        ) : (
                          <span className="text-slate-400">—</span>
                        )}
                      </Td>
                    </tr>
                  ))
                )}
              </tbody>
            </table>
          </div>

          {/* Footer avec indicateur de chargement */}
          {filteredItems.length > 0 && (
            <div className="p-3 border-t text-right">
              <div className="text-sm text-slate-500">
                {isFetching ? (
                  <span className="inline-flex items-center gap-1">
                    <Loader2 className="w-3 h-3 animate-spin" />
                    Mise à jour…
                  </span>
                ) : (
                  `${filteredItems.length} appel${filteredItems.length > 1 ? 's' : ''} à virement${filteredItems.length > 1 ? 's' : ''} affiché${filteredItems.length > 1 ? 's' : ''}`
                )}
              </div>
            </div>
          )}
        </section>
      ) : (
        <section className="rounded-2xl border bg-white">
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b bg-slate-50/80">
                  <Th>Salarié·e</Th>
                  <Th>Contrat</Th>
                  <Th>Profession</Th>
                  <Th>Début contrat</Th>
                  <Th>Fin contrat</Th>
                  <Th>Période concernée</Th>
                  <Th className="text-right">Net à payer</Th>
                  <Th className="text-center">Marquer comme payé</Th>
                </tr>
              </thead>
              <tbody>
                {/* Unpaid first */}
                {isLoading ? (
                  <tr><td colSpan={8} className="py-12 text-center text-slate-500"><Loader2 className="w-4 h-4 inline animate-spin mr-2"/> Chargement…</td></tr>
                ) : isError ? (
                  <tr><td colSpan={8} className="py-12 text-center text-rose-500">Erreur : {(error as any)?.message || 'imprévue'}</td></tr>
                ) : (clientUnpaid.length === 0 && clientRecent.length === 0) ? (
                  <tr><td colSpan={8} className="py-12 text-center text-slate-500">Aucun virement de salaires trouvé.</td></tr>
                ) : (
                  <>
                    {clientUnpaid.map((it) => (
                      <tr key={`unpaid-${it.source}-${it.id}`} className="border-b last:border-b-0 hover:bg-slate-50/50">
                        <Td>
                          {it.salarie_matricule ? (
                            <a href={`/salaries/${encodeURIComponent(it.salarie_matricule)}`} target="_blank" rel="noreferrer" className="text-blue-600 hover:underline font-medium">
                              {it.salarie || it.salarie_matricule}
                            </a>
                          ) : (
                            it.salarie || '—'
                          )}
                        </Td>
                        <Td>
                          {it.contract_id && it.reference ? (
                            <a
                              href={it.kind === 'RG' ? `/contrats-rg/${encodeURIComponent(it.contract_id)}` : (it.kind === 'CDDU_MULTI' ? `/contrats-multi/${encodeURIComponent(it.contract_id)}` : `/contrats/${encodeURIComponent(it.contract_id)}`)}
                              target="_blank"
                              rel="noreferrer"
                              className="text-blue-600 hover:underline font-medium"
                            >
                              {it.reference}
                            </a>
                          ) : (
                            <span className="font-medium">{it.reference || '—'}</span>
                          )}
                        </Td>
                        <Td>{it.profession || '—'}</Td>
                        <Td>{formatFR(it.date_debut || '')}</Td>
                        <Td>{maskEndDate(it.date_fin || '')}</Td>
                        <Td>{formatPeriode(it.periode)}</Td>
                        <Td className="text-right font-medium">{it.net_a_payer != null ? formatCurrency(it.net_a_payer) : '—'}</Td>
                        <Td className="text-center">
                          {it.source === 'payslip' ? (
                            <button
                              type="button"
                              onClick={() => markPayslipDone(it.id)}
                              className="px-2 py-1 text-xs rounded-md border hover:bg-emerald-50 hover:border-emerald-300 text-emerald-700"
                              title="Marquer le virement comme effectué"
                            >
                              Marquer
                            </button>
                          ) : (
                            <button type="button" disabled className="px-2 py-1 text-xs rounded-md border opacity-60 cursor-not-allowed" title="Non disponible">Marquer</button>
                          )}
                        </Td>
                      </tr>
                    ))}
                    {clientRecent.length > 0 && (
                      <tr className="bg-slate-50/50">
                        <td colSpan={8} className="px-3 py-2 text-xs text-slate-500">Récemment virés (≤ 30 jours)</td>
                      </tr>
                    )}
                    {clientRecent.map((it) => (
                      <tr key={`recent-${it.source}-${it.id}`} className="border-b last:border-b-0 hover:bg-slate-50/50">
                        <Td>
                          {it.salarie_matricule ? (
                            <a href={`/salaries/${encodeURIComponent(it.salarie_matricule)}`} target="_blank" rel="noreferrer" className="text-blue-600 hover:underline font-medium">
                              {it.salarie || it.salarie_matricule}
                            </a>
                          ) : (
                            it.salarie || '—'
                          )}
                        </Td>
                        <Td>
                          {it.contract_id && it.reference ? (
                            <a
                              href={it.kind === 'RG' ? `/contrats-rg/${encodeURIComponent(it.contract_id)}` : (it.kind === 'CDDU_MULTI' ? `/contrats-multi/${encodeURIComponent(it.contract_id)}` : `/contrats/${encodeURIComponent(it.contract_id)}`)}
                              target="_blank"
                              rel="noreferrer"
                              className="text-blue-600 hover:underline font-medium"
                            >
                              {it.reference}
                            </a>
                          ) : (
                            <span className="font-medium">{it.reference || '—'}</span>
                          )}
                        </Td>
                        <Td>{it.profession || '—'}</Td>
                        <Td>{formatFR(it.date_debut || '')}</Td>
                        <Td>{maskEndDate(it.date_fin || '')}</Td>
                        <Td>{formatPeriode(it.periode)}</Td>
                        <Td className="text-right font-medium">{it.net_a_payer != null ? formatCurrency(it.net_a_payer) : '—'}</Td>
                        <Td className="text-center">
                          <span className="inline-flex items-center px-2 py-1 rounded-full text-xs bg-emerald-100 text-emerald-800">Oui</span>
                        </Td>
                      </tr>
                    ))}
                  </>
                )}
              </tbody>
            </table>
          </div>
        </section>
      )}
      {aboutOpen && (
        <div className="fixed inset-0 z-[1000]">
          <div
            className="absolute inset-0 bg-black/40"
            onClick={() => setAboutOpen(false)}
          />
          <div className="absolute inset-0 flex items-center justify-center p-4">
            <div role="dialog" aria-modal="true" aria-labelledby="about-virements-title" className="w-full max-w-lg rounded-2xl border bg-white shadow-xl">
              <div className="p-5 border-b flex items-start justify-between">
                <div>
                  <h2 id="about-virements-title" className="text-base font-semibold">Gestion des virements de salaires</h2>
                </div>
                <button onClick={() => setAboutOpen(false)} className="text-slate-500 hover:text-slate-900">✕</button>
              </div>
              <div className="p-5 space-y-4 text-sm">
                <p>
                 En fin de mois, nous vous envoyons un <strong>appel à virement</strong> avec le <strong>total des salaires nets</strong> de la période concernée.
                </p>
                <p>
                  Dès réception de votre virement, nous <strong>redistribuons les salaires à vos salariés</strong>. Vous pouvez suivre l’état dans le tableau ci-dessous (colonnes « Virement reçu » et « Salaires payés »).
                </p>
                <div className="rounded-lg border p-3">
                  <div className="text-xs uppercase tracking-wide text-slate-500 mb-2">Coordonnées bancaires (salaires)</div>
                  <div className="flex flex-col gap-2">
                    <div className="flex items-center justify-between gap-2 rounded-md bg-slate-50 px-2 py-2">
                      <div>
                        <div className="text-[11px] text-slate-500">Bénéficiaire</div>
                        <div className="font-mono text-xs break-all">ODENTAS MEDIA SAS</div>
                      </div>
                      <button
                        type="button"
                        onClick={() => { navigator.clipboard?.writeText('ODENTAS MEDIA SAS').then(()=>{ setCopiedField('benef'); setTimeout(()=>setCopiedField(null), 1400); }); }}
                        className="inline-flex items-center gap-1 text-xs px-2 py-1 rounded-md border hover:bg-slate-100"
                        aria-label="Copier le bénéficiaire"
                      >
                        {copiedField === 'benef' ? <Check className="w-3.5 h-3.5" /> : <Copy className="w-3.5 h-3.5" />} Copier
                      </button>
                    </div>
                    <div className="flex items-center justify-between gap-2 rounded-md bg-slate-50 px-2 py-2">
                      <div>
                        <div className="text-[11px] text-slate-500">IBAN</div>
                        <div className="font-mono text-xs break-all">FR76 1695 8000 0141 0850 9729 813</div>
                      </div>
                      {org?.iban && (
                        <button
                          type="button"
                          onClick={() => { navigator.clipboard?.writeText("FR76 1695 8000 0141 0850 9729 813" as string).then(()=>{ setCopiedField('iban'); setTimeout(()=>setCopiedField(null), 1400); }); }}
                          className="inline-flex items-center gap-1 text-xs px-2 py-1 rounded-md border hover:bg-slate-100"
                          aria-label="Copier l’IBAN"
                        >
                          {copiedField === 'iban' ? <Check className="w-3.5 h-3.5" /> : <Copy className="w-3.5 h-3.5" />} Copier
                        </button>
                      )}
                    </div>
                    <div className="flex items-center justify-between gap-2 rounded-md bg-slate-50 px-2 py-2">
                      <div>
                        <div className="text-[11px] text-slate-500">BIC</div>
                        <div className="font-mono text-xs break-all">QNTOFRP1XXX</div>
                      </div>
                      {org?.bic && (
                        <button
                          type="button"
                          onClick={() => { navigator.clipboard?.writeText("QNTOFRP1XXX" as string).then(()=>{ setCopiedField('bic'); setTimeout(()=>setCopiedField(null), 1400); }); }}
                          className="inline-flex items-center gap-1 text-xs px-2 py-1 rounded-md border hover:bg-slate-100"
                          aria-label="Copier le BIC"
                        >
                          {copiedField === 'bic' ? <Check className="w-3.5 h-3.5" /> : <Copy className="w-3.5 h-3.5" />} Copier
                        </button>
                      )}
                    </div>
                    <p className="text-xs text-slate-500 mt-2">Ce compte bancaire est réservé à la réception des virements de salaires.</p>
                  </div>
                </div>
              </div>
              <div className="p-4 border-t flex justify-end">
                <button onClick={() => setAboutOpen(false)} className="px-3 py-2 rounded-md border hover:bg-slate-50 text-sm">Fermer</button>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// --- Composants utilitaires ---
function Th({ children, className = "" }: { children: React.ReactNode; className?: string }) {
  return (
    <th className={`text-left font-medium px-3 py-3 ${className}`}>
      {children}
    </th>
  );
}

function Td({ children, className = "" }: { children: React.ReactNode; className?: string }) {
  return (
    <td className={`px-3 py-3 ${className}`}>
      {children}
    </td>
  );
}

function StatusBadge({ status, date }: { status?: boolean | string; date?: string | null }) {
  const val = toBoolish(status);
  if (val === true) {
    return (
      <div className="flex flex-col items-center gap-1">
        <span className="inline-flex items-center px-2 py-1 rounded-full text-xs bg-emerald-100 text-emerald-800">
          ✓ Oui
        </span>
        {date && (
          <span className="text-[10px] text-slate-500">
            {formatFR(date)}
          </span>
        )}
      </div>
    );
  } else if (val === false) {
    return (
      <span className="inline-flex items-center px-2 py-1 rounded-full text-xs bg-slate-100 text-slate-600">
        ✗ Non
      </span>
    );
  } else {
    return <span className="text-slate-400">—</span>;
  }
}
