import { useEffect } from "react";
import { useNavigate } from "@tanstack/react-router";
import { toast } from "sonner";
import {
  Banknote,
  ArrowRight,
  Lock,
  Loader2,
  Trash2,
  CheckCircle2,
  AlertCircle,
} from "lucide-react";

import { Button, Card, Chip } from "@rubis/ui";
import { useSubscription } from "@/lib/billing";
import {
  useBankConnections,
  useBankingSettings,
  useBankingStatus,
  useDisconnectBank,
  useInitBanking,
  useUpdateBankingSettings,
  type BankConnection,
  type BankingReconciliationMode,
} from "@/lib/banking";

/**
 * BankingSection — carte Banque dans /parametres.
 *
 * 3 états visuels :
 *  - Free : upsell card (CTA "Passer au plan Pro")
 *  - Pro/Business + 0 banque : carte vide avec CTA "Connecter une banque"
 *  - Pro/Business + 1 banque : carte connectée (logo, accounts, bouton
 *    déconnecter, toggle mode de réconciliation)
 *
 * Détection ?banking=connected|error dans l'URL : affiche un toast et
 * nettoie l'URL (replace, pas de history entry). Évite le toast en
 * boucle si on F5.
 */
type BankingSectionProps = {
  /** Params lus depuis la route parent (cf. parametres.tsx → searchSchema). */
  callbackStatus?: "connected" | "error";
  callbackReason?: string;
};

export function BankingSection({
  callbackStatus,
  callbackReason,
}: BankingSectionProps) {
  const { data: status } = useBankingStatus();
  const { data: sub } = useSubscription();
  const isPaid = sub?.plan === "pro" || sub?.plan === "business";

  const navigate = useNavigate();
  const connectionsQuery = useBankConnections({
    enabled: status?.enabled === true && isPaid,
  });

  // Toast post-callback : on lit la search bag et on nettoie l'URL.
  useEffect(() => {
    if (!callbackStatus) return;

    if (callbackStatus === "connected") {
      toast.success("Banque connectée. Récupération des comptes en cours.");
      void connectionsQuery.refetch();
    } else {
      toast.error(
        callbackReason
          ? `Connexion impossible (${callbackReason}). Réessayez.`
          : "Connexion impossible. Réessayez.",
      );
    }

    // Nettoie l'URL pour ne pas re-déclencher le toast au refresh / nav.
    void navigate({
      to: "/parametres",
      search: {},
      replace: true,
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [callbackStatus, callbackReason]);

  if (!isPaid) {
    return <UpsellCard />;
  }

  return (
    <BankingPaidView
      isLoading={connectionsQuery.isLoading}
      connections={connectionsQuery.data ?? []}
    />
  );
}

// --------------------------------------------------------------------
// Upsell (Free) — visuel cohérent avec la section Marque (Business)
// --------------------------------------------------------------------

function UpsellCard() {
  return (
    <Card padding="md" className="flex items-center justify-between gap-4 flex-wrap">
      <div className="flex items-start gap-3">
        <div className="rounded-full bg-rubis-glow p-2 text-rubis">
          <Lock size={16} aria-hidden="true" />
        </div>
        <div>
          <p className="text-[10.5px] uppercase tracking-[0.12em] text-rubis font-semibold">
            Plan Pro ou Business requis
          </p>
          <p className="mt-1 text-[14px] text-ink-2 leading-snug max-w-[420px]">
            Connectez votre banque pour détecter automatiquement les factures
            payées et arrêter les relances inutiles.
          </p>
        </div>
      </div>
      <Button size="sm" variant="primary" asChild>
        <a href="/parametres/abonnement">
          Passer au plan Pro
          <ArrowRight size={13} aria-hidden="true" />
        </a>
      </Button>
    </Card>
  );
}

// --------------------------------------------------------------------
// Vue Pro/Business
// --------------------------------------------------------------------

function BankingPaidView({
  isLoading,
  connections,
}: {
  isLoading: boolean;
  connections: BankConnection[];
}) {
  const active = connections.find((c) => c.state !== "revoked");

  if (isLoading) {
    return (
      <Card padding="md" className="flex items-center gap-2 text-ink-3 text-[13px]">
        <Loader2 size={14} className="animate-spin" aria-hidden="true" />
        Chargement…
      </Card>
    );
  }

  return (
    <div className="flex flex-col gap-4">
      {active ? (
        <ConnectedBankCard connection={active} />
      ) : (
        <ConnectCta />
      )}
      <ReconciliationModeToggle />
    </div>
  );
}

// --------------------------------------------------------------------
// CTA "Connecter une banque"
// --------------------------------------------------------------------

function ConnectCta() {
  const initMutation = useInitBanking();

  const onConnect = async () => {
    try {
      const { webviewUrl } = await initMutation.mutateAsync();
      // Full nav vers Powens — pas un popup, parce que le retour fait
      // un redirect 302 via le tunnel API.
      window.location.href = webviewUrl;
    } catch (err) {
      const msg =
        err instanceof Error ? err.message : "Connexion impossible. Réessayez.";
      toast.error(msg);
    }
  };

  return (
    <Card padding="md" className="flex items-center justify-between gap-4 flex-wrap">
      <div className="flex items-start gap-3">
        <div className="rounded-full bg-rubis-glow p-2 text-rubis">
          <Banknote size={16} aria-hidden="true" />
        </div>
        <div>
          <p className="font-display text-[16px] font-semibold text-ink">
            Aucune banque connectée
          </p>
          <p className="mt-1 text-[13px] text-ink-3 leading-snug max-w-[420px]">
            Rubis lit vos virements entrants pour détecter les factures payées.
            Lecture seule. Aucun déplacement de fonds.
          </p>
        </div>
      </div>
      <Button size="sm" variant="primary" onClick={onConnect} loading={initMutation.isPending}>
        <Banknote size={14} aria-hidden="true" />
        Connecter une banque
      </Button>
    </Card>
  );
}

// --------------------------------------------------------------------
// Carte "Banque connectée"
// --------------------------------------------------------------------

function ConnectedBankCard({ connection }: { connection: BankConnection }) {
  const disconnect = useDisconnectBank();

  const onDisconnect = async () => {
    if (!window.confirm(`Déconnecter ${connection.bankName} ?`)) return;
    try {
      await disconnect.mutateAsync(connection.id);
      toast.success("Banque déconnectée.");
    } catch {
      toast.error("Déconnexion impossible. Réessayez.");
    }
  };

  return (
    <Card padding="md" className="flex flex-col gap-4">
      <header className="flex items-start justify-between gap-3 flex-wrap">
        <div className="flex items-center gap-3">
          <div className="rounded-full bg-rubis-glow p-2 text-rubis">
            <Banknote size={18} aria-hidden="true" />
          </div>
          <div>
            <p className="font-display text-[16px] font-semibold text-ink">
              {connection.bankName}
            </p>
            <p className="mt-0.5 flex items-center gap-1.5 text-[12px] text-ink-3">
              <StateBadge state={connection.state} />
              {connection.lastSyncAt && (
                <span>
                  · synchronisé {formatRelative(connection.lastSyncAt)}
                </span>
              )}
            </p>
          </div>
        </div>
        <Button
          size="sm"
          variant="secondary"
          onClick={onDisconnect}
          loading={disconnect.isPending}
        >
          <Trash2 size={14} aria-hidden="true" />
          Déconnecter
        </Button>
      </header>

      {connection.lastError && (
        <div className="rounded-md border border-rubis-deep/20 bg-rubis-glow/30 px-3 py-2 text-[12.5px] text-rubis-deep">
          {connection.lastError}
        </div>
      )}

      <ul className="flex flex-col divide-y divide-ink/5">
        {connection.accounts.length === 0 ? (
          <li className="py-2 text-[13px] text-ink-3">
            Aucun compte récupéré pour cette banque.
          </li>
        ) : (
          connection.accounts.map((a) => (
            <li
              key={a.id}
              className="py-2.5 flex items-center justify-between gap-3 text-[13px]"
            >
              <div>
                <p className="font-medium text-ink">{a.name}</p>
                {a.ibanMasked && (
                  <p className="font-mono text-[11.5px] text-ink-3 tracking-tight">
                    {a.ibanMasked}
                  </p>
                )}
              </div>
              {a.balanceCents !== null && (
                <p className="font-mono text-[12.5px] text-ink-2">
                  {(a.balanceCents / 100).toLocaleString("fr-FR", {
                    style: "currency",
                    currency: a.currency,
                  })}
                </p>
              )}
            </li>
          ))
        )}
      </ul>
    </Card>
  );
}

function StateBadge({ state }: { state: string }) {
  if (state === "active") {
    return (
      <span className="inline-flex items-center gap-1 text-rubis">
        <CheckCircle2 size={11} aria-hidden="true" />
        Actif
      </span>
    );
  }
  return (
    <span className="inline-flex items-center gap-1 text-rubis-deep">
      <AlertCircle size={11} aria-hidden="true" />
      {state}
    </span>
  );
}

// --------------------------------------------------------------------
// Toggle mode de réconciliation
// --------------------------------------------------------------------

function ReconciliationModeToggle() {
  const { data, isLoading } = useBankingSettings();
  const mutate = useUpdateBankingSettings();

  if (isLoading || !data) return null;

  const current = data.reconciliationMode;

  const setMode = (mode: BankingReconciliationMode) => {
    if (mode === current) return;
    void mutate.mutateAsync(mode).then(
      () => toast.success(mode === "auto" ? "Mode automatique activé." : "Mode manuel activé."),
      () => toast.error("Mise à jour impossible. Réessayez."),
    );
  };

  return (
    <Card padding="md" className="flex flex-col gap-3">
      <div>
        <p className="text-[10.5px] uppercase tracking-[0.12em] text-rubis font-semibold">
          Réconciliation
        </p>
        <p className="mt-1 text-[13px] text-ink-2 leading-snug">
          Quand un virement matche une facture en attente, Rubis peut soit
          vous suggérer le match, soit la marquer payée automatiquement.
        </p>
      </div>
      <div className="flex flex-wrap gap-2">
        <Chip selected={current === "manual"} onClick={() => setMode("manual")}>
          Manuelle — je valide chaque match
        </Chip>
        <Chip selected={current === "auto"} onClick={() => setMode("auto")}>
          Automatique — match exact = facture payée
        </Chip>
      </div>
    </Card>
  );
}

// --------------------------------------------------------------------
// Helpers
// --------------------------------------------------------------------

function formatRelative(iso: string): string {
  const diff = Date.now() - new Date(iso).getTime();
  const min = Math.round(diff / 60_000);
  if (min < 1) return "à l'instant";
  if (min < 60) return `il y a ${min} min`;
  const h = Math.round(min / 60);
  if (h < 24) return `il y a ${h} h`;
  const d = Math.round(h / 24);
  return `il y a ${d} j`;
}
