"use client";

import { useMemo, useState, useEffect } from "react";
import Link from "next/link";
import { useQuery } from "@tanstack/react-query";
import { api } from "@/lib/fetcher";
import { Loader2, CheckCircle2, XCircle, FileDown, Edit, ChevronLeft, ChevronRight } from "lucide-react";
import { usePageTitle } from "@/hooks/usePageTitle";
import { useStaffOrgSelection } from "@/hooks/useStaffOrgSelection";

// ---------------- Types ----------------
type SepaInfo = {
  enabled: boolean;
  iban?: string | null;
  bic?: string | null;
  mandate_url?: string | null;
};

type Invoice = {
  id: string;
  numero: string | null;
  periode: string | null; // ex: "Août 2025"
  date: string | null; // ISO date
  montant_ht: number; // euros
  montant_ttc: number; // euros
  statut: "payee" | "annulee" | "prete" | "emise" | "en_cours" | string | null;
  pdf?: string | null;
};

type BillingResponse = {
  sepa: SepaInfo & { state?: string; label?: string };
  factures: {
    items: Invoice[];
    page: number;
    limit: number;
    hasMore: boolean;
    total?: number;
    totalPages?: number;
  };
};

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

// -------------- Helpers --------------
const fmtEUR = new Intl.NumberFormat("fr-FR", { style: "currency", currency: "EUR" });
function fmtDateFR(iso?: string) {
  if (!iso) return "—";
  const d = new Date(iso);
  return d.toLocaleDateString("fr-FR", { day: "2-digit", month: "2-digit", year: "numeric" });
}

function Badge({ tone = "default", children }: { tone?: "ok" | "warn" | "error" | "default"; children: React.ReactNode }) {
  const cls =
    tone === "ok"
      ? "bg-emerald-100 text-emerald-800"
      : tone === "warn"
      ? "bg-amber-100 text-amber-800"
      : tone === "error"
      ? "bg-rose-100 text-rose-800"
      : "bg-slate-100 text-slate-700";
  return <span className={`text-xs px-2 py-1 rounded-full ${cls}`}>{children}</span>;
}

function Section({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <section className="rounded-2xl border bg-white">
      <div className="px-4 py-3 border-b font-medium text-slate-700 bg-slate-50/60">
        {title}
      </div>
      <div className="p-4">{children}</div>
    </section>
  );
}

// -------------- Composant Pagination --------------
type PaginationProps = {
  page: number;
  totalPages: number;
  total: number;
  limit: number;
  onPageChange: (page: number) => void;
  onLimitChange: (limit: number) => void;
  isFetching?: boolean;
  itemsCount: number;
  position?: 'top' | 'bottom';
};

function Pagination({ page, totalPages, total, limit, onPageChange, onLimitChange, isFetching, itemsCount, position = 'bottom' }: PaginationProps) {
  return (
    <div className={`p-3 flex flex-col sm:flex-row items-center gap-3 ${position === 'bottom' ? 'border-t' : ''}`}>
      {/* Navigation */}
      <div className="flex items-center gap-2">
        <button 
          onClick={() => onPageChange(Math.max(1, page - 1))} 
          disabled={page === 1} 
          className="px-2 py-1 rounded-lg border disabled:opacity-40 hover:bg-slate-50 disabled:hover:bg-transparent"
        >
          <ChevronLeft className="w-4 h-4"/>
        </button>
        <div className="text-sm">
          Page <strong>{page}</strong> sur <strong>{totalPages || 1}</strong>
        </div>
        <button 
          onClick={() => onPageChange(page + 1)} 
          disabled={page >= totalPages} 
          className="px-2 py-1 rounded-lg border disabled:opacity-40 hover:bg-slate-50 disabled:hover:bg-transparent"
        >
          <ChevronRight className="w-4 h-4"/>
        </button>
      </div>
      
      {/* Sélecteur de limite */}
      <div className="flex items-center gap-2 text-sm">
        <span className="text-slate-600">Afficher :</span>
        <select
          value={limit}
          onChange={(e) => onLimitChange(parseInt(e.target.value, 10))}
          className="px-2 py-1 rounded-lg border bg-white text-sm"
        >
          <option value={10}>10</option>
          <option value={50}>50</option>
          <option value={100}>100</option>
        </select>
      </div>
      
      {/* Informations */}
      <div className="sm:ml-auto text-sm text-slate-600">
        {isFetching ? (
          <span className="flex items-center gap-1">
            <Loader2 className="w-3 h-3 animate-spin" />
            Mise à jour…
          </span>
        ) : (
          <span>
            {total > 0 ? (
              <>
                <strong>{total}</strong> facture{total > 1 ? 's' : ''} au total
                {itemsCount > 0 && ` • ${itemsCount} affichée${itemsCount > 1 ? 's' : ''}`}
              </>
            ) : (
              'Aucune facture'
            )}
          </span>
        )}
      </div>
    </div>
  );
}

// -------------- Data hook --------------
function useBilling(page: number, limit: number, selectedOrg?: { id: string; name: string; api_name?: string } | null) {
  // Récupération dynamique des infos client via /api/me
  const { data: clientInfo } = useQuery({
    queryKey: ["client-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 {
          id: me.active_org_id || null,
          name: me.active_org_name || "Organisation",
          api_name: me.active_org_api_name
        } as ClientInfo;
      } catch {
        return null;
      }
    },
    staleTime: 30_000, // Cache 30s
  });

  // Si selectedOrg est fourni (staff), créer un clientInfo override avec toutes les infos
  const effectiveClientInfo = selectedOrg 
    ? { id: selectedOrg.id, name: selectedOrg.name, api_name: selectedOrg.api_name } as ClientInfo
    : clientInfo;

  return useQuery<BillingResponse>({
    queryKey: ["billing", page, limit, effectiveClientInfo?.id], // Inclure l'ID client dans la queryKey
    queryFn: () => api(`/facturation?page=${page}&limit=${limit}`, {}, effectiveClientInfo), // Passer clientInfo au helper api()
    staleTime: 15_000,
    enabled: !!effectiveClientInfo, // Ne pas exécuter si pas d'infos client
  });
}

// -------------- Page --------------
export default function FacturationPage() {
  usePageTitle("Facturation");
  
  // Helper pour valider les UUIDs
  const isValidUUID = (str: string | null): boolean => {
    if (!str) return false;
    return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(str);
  };
  
  // Zustand store pour la sélection d'organisation (staff)
  const { 
    selectedOrgId: globalSelectedOrgId, 
    setSelectedOrg: setGlobalSelectedOrg 
  } = useStaffOrgSelection();
  
  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(10);
  
  // État local initialisé avec la valeur globale si elle est un UUID valide
  const [selectedOrgId, setSelectedOrgId] = useState<string>(
    (globalSelectedOrgId && isValidUUID(globalSelectedOrgId)) ? globalSelectedOrgId : ""
  );
  
  // Détection staff
  const { data: meData } = useQuery({
    queryKey: ["me-info"],
    queryFn: async () => {
      try {
        const res = await fetch('/api/me', { cache: 'no-store', credentials: 'include' });
        if (!res.ok) return null;
        return await res.json();
      } catch { return null; }
    },
  });
  
  // Chargement des organisations (staff uniquement)
  const { data: organizations } = useQuery({
    queryKey: ["organizations"],
    queryFn: async () => {
      try {
        const res = await fetch('/api/organizations', { cache: 'no-store', credentials: 'include' });
        if (!res.ok) return [];
        const data = await res.json();
        return (data.items || []).map((org: any) => ({ 
          id: org.id, 
          name: org.name,
          api_name: org.structure_api || org.key 
        }));
      } catch { return []; }
    },
    enabled: !!meData?.is_staff,
  });
  
  // Synchronisation bidirectionnelle : global → local
  useEffect(() => {
    if (meData?.is_staff && globalSelectedOrgId && isValidUUID(globalSelectedOrgId)) {
      setSelectedOrgId(globalSelectedOrgId);
    }
  }, [globalSelectedOrgId, meData?.is_staff]);
  
  // Trouver l'organisation complète sélectionnée (pour passer api_name à useBilling)
  const selectedOrgData = selectedOrgId 
    ? organizations?.find((org: any) => org.id === selectedOrgId) 
    : null;
  
  const { data, isLoading, isError, error, isFetching } = useBilling(page, limit, selectedOrgData || null);

  const items = data?.factures.items ?? [];
  const hasMore = data?.factures.hasMore ?? false;
  const total = data?.factures.total ?? 0;
  const totalPages = data?.factures.totalPages ?? 0;

  return (
    <main className="space-y-5">
      {/* Sélecteur d'organisation (visible uniquement par le staff) */}
      {meData?.is_staff && (
        <Section title="Sélection de l'organisation">
          <div className="flex items-center gap-2">
            <label className="text-sm font-medium text-slate-700">Organisation :</label>
            <select
              className="px-3 py-2 rounded-lg border bg-white text-sm min-w-[200px]"
              value={selectedOrgId}
              onChange={(e) => {
                const newOrgId = e.target.value;
                setSelectedOrgId(newOrgId);
                setPage(1);
                
                // Synchronisation bidirectionnelle : local → global
                if (newOrgId) {
                  const selectedOrg = organizations?.find((org: any) => org.id === newOrgId);
                  if (selectedOrg) {
                    setGlobalSelectedOrg(newOrgId, selectedOrg.name);
                  }
                } else {
                  setGlobalSelectedOrg(null, null);
                }
              }}
              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>
        </Section>
      )}
      
      {/* SEPA / IBAN */}
      <Section title="Prélèvement automatique SEPA">
        {isLoading && (
          <div className="text-sm text-slate-500 flex items-center gap-2"><Loader2 className="w-4 h-4 animate-spin"/> Chargement…</div>
        )}
        {isError && (
          <div className="text-sm text-rose-600">Impossible de charger les infos de facturation : {(error as any)?.message || "erreur"}</div>
        )}
        {data && (
          <div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
            {/* Etat SEPA */}
            <div className="rounded-xl border p-4 flex items-center justify-between">
              <div className="flex items-center gap-3">
                {data.sepa.enabled ? (
                  <CheckCircle2 className="w-5 h-5 text-emerald-600"/>
                ) : (
                  <XCircle className="w-5 h-5 text-amber-500"/>
                )}
                <div>
                  <div className="font-medium">{data.sepa.enabled ? "Mis en place" : "Non activé"}</div>
                  <div className="text-xs text-slate-500">Mandat SEPA {data.sepa.enabled ? "actif" : "non signé"}</div>
                </div>
              </div>
              <div>
                {data.sepa.enabled ? (
                  <Badge tone="ok">Actif</Badge>
                ) : data.sepa.mandate_url ? (
                  <a href={data.sepa.mandate_url} target="_blank" rel="noreferrer" className="text-sm underline">Signer le mandat</a>
                ) : (
                  <span className="text-xs text-slate-400">—</span>
                )}
              </div>
            </div>

            {/* Coordonnées bancaires */}
            <div className="lg:col-span-2 rounded-xl border p-4">
              <div className="flex items-center justify-between mb-3">
                <div className="font-medium">Vos coordonnées bancaires</div>
                <button className="inline-flex items-center gap-2 text-sm underline"><Edit className="w-4 h-4"/> Modifier</button>
              </div>
              <div className="space-y-2 text-sm">
                <div className="grid grid-cols-[120px_1fr] gap-2 items-center">
                  <div className="text-slate-500">Votre IBAN</div>
                  <div className="font-mono break-all">{data.sepa.iban || <span className="text-slate-400">—</span>}</div>
                </div>
                <div className="grid grid-cols-[120px_1fr] gap-2 items-center">
                  <div className="text-slate-500">Votre BIC</div>
                  <div className="font-mono break-all">{data.sepa.bic || <span className="text-slate-400">—</span>}</div>
                </div>
              </div>
            </div>
          </div>
        )}
      </Section>

      {/* Pagination supérieure */}
      {items.length > 0 && (
        <section className="rounded-2xl border bg-white">
          <Pagination
            page={page}
            totalPages={totalPages}
            total={total}
            limit={limit}
            onPageChange={(newPage) => setPage(newPage)}
            onLimitChange={(newLimit) => { setLimit(newLimit); setPage(1); }}
            isFetching={isFetching}
            itemsCount={items.length}
            position="top"
          />
        </section>
      )}

      {/* Factures */}
      <Section title="Vos factures">
        <div className="text-xs text-slate-500 mb-3 flex items-center gap-4">
          <div className="flex items-center gap-2"><span className="w-2 h-2 rounded-full bg-emerald-500 inline-block"/> Facture payée</div>
          <div className="flex items-center gap-2"><span className="w-2 h-2 rounded-full bg-slate-400 inline-block"/> Facture émise</div>
          <div className="flex items-center gap-2"><span className="w-2 h-2 rounded-full bg-rose-500 inline-block"/> Facture annulée</div>
          <div className="flex items-center gap-2"><span className="w-2 h-2 rounded-full bg-blue-500 inline-block"/> Facture en cours</div>
        </div>

        {!data && isLoading && (
          <div className="text-sm text-slate-500 flex items-center gap-2"><Loader2 className="w-4 h-4 animate-spin"/> Chargement…</div>
        )}

        {data && (
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead className="text-left bg-slate-50">
                <tr className="border-b">
                  <th className="px-3 py-2">Statut</th>
                  <th className="px-3 py-2">Numéro</th>
                  <th className="px-3 py-2">Période concernée</th>
                  <th className="px-3 py-2">Date</th>
                  <th className="px-3 py-2 text-right">HT</th>
                  <th className="px-3 py-2 text-right">TTC</th>
                  <th className="px-3 py-2">PDF</th>
                </tr>
              </thead>
              <tbody>
                {items.length === 0 && (
                  <tr>
                    <td colSpan={7} className="px-3 py-6 text-center text-slate-500">Aucune facture.</td>
                  </tr>
                )}
                {items.map((f) => (
                  <tr key={f.id} className="border-b last:border-b-0">
                    <td className="px-3 py-2">
                      {f.statut === "payee" ? (
                        <span className="inline-flex items-center gap-2"><span className="w-2 h-2 rounded-full bg-emerald-500 inline-block"/> Payée</span>
                      ) : f.statut === "annulee" ? (
                        <span className="inline-flex items-center gap-2"><span className="w-2 h-2 rounded-full bg-rose-500 inline-block"/> Annulée</span>
                      ) : f.statut === "en_cours" ? (
                        <span className="inline-flex items-center gap-2"><span className="w-2 h-2 rounded-full bg-blue-500 inline-block"/> En cours</span>
                      ) : (
                        <span className="inline-flex items-center gap-2"><span className="w-2 h-2 rounded-full bg-slate-400 inline-block"/> Émise</span>
                      )}
                    </td>
                    <td className="px-3 py-2 font-medium">{f.numero || "—"}</td>
                    <td className="px-3 py-2">{f.periode || "—"}</td>
                    <td className="px-3 py-2">{fmtDateFR(f.date || undefined)}</td>
                    <td className="px-3 py-2 text-right">{fmtEUR.format(f.montant_ht || 0)}</td>
                    <td className="px-3 py-2 text-right">{fmtEUR.format(f.montant_ttc || 0)}</td>
                    <td className="px-3 py-2">
                      {f.pdf ? (
                        <a href={f.pdf} target="_blank" rel="noreferrer" className="inline-flex items-center gap-2 underline">
                          <FileDown className="w-4 h-4"/> Télécharger
                        </a>
                      ) : (
                        <span className="text-slate-400">—</span>
                      )}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}

        {/* Pagination inférieure */}
        {data && (
          <div className="mt-4">
            <Pagination
              page={page}
              totalPages={totalPages}
              total={total}
              limit={limit}
              onPageChange={(newPage) => setPage(newPage)}
              onLimitChange={(newLimit) => { setLimit(newLimit); setPage(1); }}
              isFetching={isFetching}
              itemsCount={items.length}
              position="bottom"
            />
          </div>
        )}
      </Section>
    </main>
  );
}
