import { useEffect, useState } from "react";
import { createFileRoute, Link } from "@tanstack/react-router";
import { ArrowLeft, ArrowRight, CreditCard, RotateCcw, Clock } from "lucide-react";
import { toast } from "sonner";
import { z } from "zod";

import {
  useOpenPortal,
  useReactivateSubscription,
  useStartCheckout,
  useSubscription,
  type BillingCycle,
} from "@/lib/billing";
import { cn } from "@/lib/utils";
import { formatDate } from "@/lib/format";
import { Gem } from "@/components/brand/Gem";

import { Button } from "@/components/ui/Button";
import { Card } from "@/components/ui/Card";
import { Eyebrow } from "@/components/ui/Eyebrow";

const searchSchema = z.object({
  checkout: z.enum(["success", "cancel"]).optional(),
  session_id: z.string().optional(),
});

export const Route = createFileRoute("/_app/parametres_/abonnement")({
  validateSearch: searchSchema,
  component: AbonnementPage,
});

function AbonnementPage() {
  const search = Route.useSearch();
  const { data: sub, isPending } = useSubscription();
  const checkout = useStartCheckout();
  const portal = useOpenPortal();
  const reactivate = useReactivateSubscription();
  const [cycle, setCycle] = useState<BillingCycle>("monthly");

  useEffect(() => {
    if (search.checkout === "success") {
      toast.success("Bienvenue sur le nouveau plan ! Activation en cours…");
    } else if (search.checkout === "cancel") {
      toast.info("Checkout annulé. Pas de souci, on en reste là.");
    }
  }, [search.checkout]);

  const onUpgrade = (plan: "pro" | "business") => {
    checkout.mutate(
      { plan, cycle },
      {
        onSuccess: ({ url }) => {
          window.location.href = url;
        },
        onError: () => toast.error("Impossible d'ouvrir Stripe. Réessaye."),
      },
    );
  };

  const onOpenPortal = () => {
    portal.mutate(undefined, {
      onSuccess: ({ url }) => {
        window.location.href = url;
      },
      onError: () => toast.error("Impossible d'ouvrir le portail. Réessaye."),
    });
  };

  const onReactivate = () => {
    reactivate.mutate(undefined, {
      onSuccess: () => toast.success("Souscription réactivée — tout repart comme avant."),
      onError: () => toast.error("Impossible de réactiver. Réessaye."),
    });
  };

  const currentPlan = sub?.plan;

  return (
    <div className="flex flex-col gap-7">
      <Link
        to="/parametres"
        className="inline-flex items-center gap-1.5 self-start text-[12.5px] text-ink-3 hover:text-rubis"
      >
        <ArrowLeft size={13} aria-hidden="true" /> Paramètres
      </Link>

      {/* Header — direct, pas trop de baratin */}
      <header className="max-w-2xl">
        <Eyebrow>Abonnement</Eyebrow>
        <h1 className="mt-2 font-display text-[30px] font-bold tracking-[-0.024em] text-ink lg:text-[36px] leading-[1.05]">
          Trois mois pour voir.
          <br />
          Puis vous <em className="text-rubis">décidez</em>.
        </h1>
        <p className="mt-3 text-[14.5px] text-ink-2 leading-relaxed">
          Pas de carte demandée pour démarrer. Au-delà de 5 factures actives,
          vous passez Pro pour continuer — quand vous êtes prêt, pas avant.
        </p>
      </header>

      {/* État courant — slim, info-dense, pas un gros bloc */}
      {!isPending && sub && (
        <CurrentPlanStrip
          state={sub}
          onOpenPortal={onOpenPortal}
          isOpeningPortal={portal.isPending}
          onReactivate={onReactivate}
          isReactivating={reactivate.isPending}
        />
      )}

      {/* Toggle cycle */}
      <div className="flex items-center justify-between gap-4 flex-wrap">
        <CycleToggle value={cycle} onChange={setCycle} />
        <p className="text-[11.5px] italic text-ink-3">
          Annulation 1-clic · pas d'engagement
        </p>
      </div>

      {/* Layout asymétrique : Pro en hero centré, Free et Business plus modestes */}
      <section className="grid grid-cols-1 gap-4 lg:grid-cols-[1fr_1.3fr_1fr] lg:gap-5 lg:items-stretch">
        <PlanFree current={currentPlan === "free"} />
        <PlanProHero
          current={currentPlan === "pro"}
          cycle={cycle}
          loading={checkout.isPending && checkout.variables?.plan === "pro"}
          onUpgrade={() => onUpgrade("pro")}
        />
        <PlanBusiness
          current={currentPlan === "business"}
          cycle={cycle}
          loading={checkout.isPending && checkout.variables?.plan === "business"}
          onUpgrade={() => onUpgrade("business")}
        />
      </section>

      {/* Footer rassurant */}
      <p className="text-[12px] text-ink-3 italic max-w-2xl leading-relaxed">
        Paiement sécurisé via Stripe — CB ou SEPA, TVA selon votre pays.
        Vous gardez la main sur votre abonnement à tout moment depuis le
        portail client.
      </p>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Strip "Plan courant" — discret mais informatif (vs gros bloc IA-template)
// ---------------------------------------------------------------------------

function CurrentPlanStrip({
  state,
  onOpenPortal,
  isOpeningPortal,
  onReactivate,
  isReactivating,
}: {
  state: ReturnType<typeof useSubscription>["data"] & {};
  onOpenPortal: () => void;
  isOpeningPortal: boolean;
  onReactivate: () => void;
  isReactivating: boolean;
}) {
  const { plan, activeInvoicesCount, caps, inGracePeriod, gracePeriodEndsAt, cancelAtPeriodEnd } =
    state;
  const limit = caps.activeInvoicesLimit;
  const isLimited = plan === "free" && limit !== null;
  const limitReached =
    isLimited && limit !== null && !inGracePeriod && activeInvoicesCount >= limit;
  const isCancelling = plan !== "free" && cancelAtPeriodEnd;

  return (
    <div
      className={cn(
        "flex items-center gap-4 rounded-card border px-5 py-4",
        // Border + bg switchent en mode "annulation programmée" pour
        // attirer l'œil — l'user doit voir tout de suite que son accès
        // s'éteint bientôt.
        isCancelling
          ? "border-rubis-deep bg-rubis-glow/30"
          : "border-line bg-white",
      )}
    >
      {isCancelling ? (
        <Clock
          size={22}
          className="shrink-0 text-rubis-deep"
          aria-hidden="true"
        />
      ) : (
        <Gem size={22} className="shrink-0" />
      )}

      <div className="flex-1 min-w-0">
        <p className="font-display text-[15px] font-bold text-ink leading-tight">
          {plan === "free" ? "Plan Rubis" : "Rubis"}
          {plan !== "free" && (
            <span className="ml-1 text-rubis">{plan === "pro" ? " Pro" : " Business"}</span>
          )}
          {isCancelling && (
            <span className="ml-2 text-[10.5px] font-bold text-rubis-deep uppercase tracking-[0.12em]">
              · Annulé
            </span>
          )}
          {!isCancelling && state.subscriptionStatus && state.subscriptionStatus !== "active" && (
            <span className="ml-2 text-[10.5px] font-medium text-rubis-deep uppercase tracking-[0.1em]">
              · {state.subscriptionStatus}
            </span>
          )}
        </p>
        <p className="mt-0.5 text-[12px] text-ink-3 leading-tight">
          {/* Cas prioritaire : annulation programmée → on insiste là-dessus */}
          {isCancelling && state.currentPeriodEnd ? (
            <>
              Accès Pro jusqu'au{" "}
              <strong className="text-rubis-deep font-semibold">
                {formatDate(state.currentPeriodEnd)}
              </strong>
              , puis retour automatique au plan Free.
            </>
          ) : (
            <>
              {plan === "free" && inGracePeriod && gracePeriodEndsAt && (
                <>
                  Période illimitée jusqu'au{" "}
                  <strong className="text-ink-2 font-medium">
                    {formatDate(gracePeriodEndsAt)}
                  </strong>
                </>
              )}
              {plan === "free" && !inGracePeriod && limit !== null && (
                <>
                  <strong
                    className={cn(
                      "tabular-nums font-medium",
                      limitReached ? "text-rubis-deep" : "text-ink-2",
                    )}
                  >
                    {activeInvoicesCount} / {limit}
                  </strong>{" "}
                  factures actives
                  {limitReached && " — limite atteinte"}
                </>
              )}
              {plan !== "free" && state.currentPeriodEnd && (
                <>
                  Renouvellement le{" "}
                  <strong className="text-ink-2 font-medium">
                    {formatDate(state.currentPeriodEnd)}
                  </strong>
                  {state.billingCycle === "yearly" ? " (annuel)" : " (mensuel)"}
                </>
              )}
            </>
          )}
        </p>
      </div>

      {/* Mini progress bar — uniquement Free post-grace, masqué si cancelling */}
      {isLimited && limit !== null && !inGracePeriod && !isCancelling && (
        <div className="hidden sm:block w-32 shrink-0">
          <div className="h-1 w-full rounded-full bg-cream-2 overflow-hidden">
            <div
              className={cn(
                "h-full transition-[width] duration-300",
                limitReached ? "bg-rubis-deep" : "bg-rubis",
              )}
              style={{
                width: `${Math.min(100, (activeInvoicesCount / limit) * 100)}%`,
              }}
            />
          </div>
        </div>
      )}

      {/* Actions : Réactiver si annulé, sinon Gérer */}
      {isCancelling ? (
        <Button
          size="sm"
          variant="primary"
          onClick={onReactivate}
          loading={isReactivating}
          className="shrink-0"
        >
          <RotateCcw size={13} aria-hidden="true" /> Réactiver
        </Button>
      ) : (
        state.hasStripeCustomer && (
          <Button
            size="sm"
            variant="ghost"
            onClick={onOpenPortal}
            loading={isOpeningPortal}
          >
            <CreditCard size={13} aria-hidden="true" /> Gérer
          </Button>
        )
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Toggle cycle — mensuel par défaut, annuel à droite avec −17%
// ---------------------------------------------------------------------------

function CycleToggle({
  value,
  onChange,
}: {
  value: BillingCycle;
  onChange: (v: BillingCycle) => void;
}) {
  return (
    <div
      role="radiogroup"
      aria-label="Cycle de facturation"
      className="inline-flex rounded-default border border-line bg-white p-0.5"
    >
      {(["monthly", "yearly"] as const).map((v) => {
        const active = v === value;
        return (
          <button
            key={v}
            type="button"
            role="radio"
            aria-checked={active}
            onClick={() => onChange(v)}
            className={cn(
              "px-4 h-9 rounded-default text-[12.5px] font-medium transition-colors cursor-pointer",
              active ? "bg-rubis text-white" : "text-ink-2 hover:bg-cream-2",
            )}
          >
            {v === "monthly" ? "Mensuel" : "Annuel"}
            {v === "yearly" && (
              <span
                className={cn(
                  "ml-1.5 text-[10px] font-semibold uppercase tracking-[0.1em]",
                  active ? "text-rubis-glow" : "text-rubis",
                )}
              >
                −17%
              </span>
            )}
          </button>
        );
      })}
    </div>
  );
}

// ---------------------------------------------------------------------------
// PlanFree — petite card sobre. Pas de pricing affiché en gros (= 0 €).
// ---------------------------------------------------------------------------

function PlanFree({ current }: { current: boolean }) {
  return (
    <div className="rounded-card border border-line bg-cream-2/40 p-6 flex flex-col">
      <div className="flex items-baseline gap-2 mb-1">
        <p className="font-display text-[16px] font-bold text-ink">Découverte</p>
        {current && <CurrentBadge />}
      </div>
      <p className="text-[11.5px] uppercase tracking-[0.12em] text-ink-3 font-semibold mb-5">
        Gratuit
      </p>

      <p className="font-display text-[28px] font-bold leading-none text-ink mb-1">
        0 €
      </p>
      <p className="text-[11.5px] text-ink-3 mb-5">3 mois illimités, puis 5 factures actives</p>

      <ul className="flex flex-col gap-2.5 text-[12.5px] text-ink-2 leading-snug">
        <FeatureLine>Tester sans poser sa CB</FeatureLine>
        <FeatureLine>Plans de relance fournis</FeatureLine>
        <FeatureLine>OCR + automatisations 3 mois</FeatureLine>
        <FeatureLine>Au-delà : 5 factures à la fois</FeatureLine>
      </ul>

      <p className="mt-auto pt-6 text-[11px] italic text-ink-3 leading-snug">
        Tout ce qu'il faut pour comprendre l'outil. Vous prendrez Pro
        quand votre volume mensuel dépasse 5 factures à relancer.
      </p>
    </div>
  );
}

// ---------------------------------------------------------------------------
// PlanProHero — la pièce maîtresse. Bg cream + gem en filigrane, prix XL.
// ---------------------------------------------------------------------------

function PlanProHero({
  current,
  cycle,
  loading,
  onUpgrade,
}: {
  current: boolean;
  cycle: BillingCycle;
  loading: boolean;
  onUpgrade: () => void;
}) {
  const monthlyPrice = cycle === "monthly" ? 19 : Math.round((190 / 12) * 100) / 100;
  const totalLabel = cycle === "monthly" ? "facturé chaque mois" : "soit 190 € facturés annuellement";

  return (
    <Card padding="none" className="relative overflow-hidden flex flex-col p-7 border-rubis shadow-card">
      {/* Gem en filigrane, bas-droite, très large pour devenir un motif */}
      <Gem
        aria-hidden="true"
        size={280}
        className="absolute -bottom-16 -right-16 text-rubis-glow opacity-70 pointer-events-none"
      />

      {/* Pastille "Recommandé" */}
      <div className="relative flex items-center gap-2 mb-3">
        <span className="inline-flex items-center gap-1.5 rounded-full bg-rubis text-white px-2.5 py-0.5 text-[10.5px] font-bold uppercase tracking-[0.12em]">
          <Gem size={10} className="text-white" />
          Le plus pris
        </span>
        {current && <CurrentBadge />}
      </div>

      <p className="relative font-display text-[24px] font-bold tracking-[-0.018em] text-ink leading-tight">
        Pour les TPE qui n'ont plus jamais à y penser
      </p>

      {/* Bloc prix — affiché de manière narrative */}
      <div className="relative mt-5 mb-5">
        <p className="font-display flex items-baseline">
          <span className="text-[44px] font-bold tabular-nums tracking-[-0.025em] text-ink leading-none">
            {monthlyPrice.toString().replace(".", ",")} €
          </span>
          <span className="ml-2 text-[13px] font-medium text-ink-3">/ mois</span>
        </p>
        <p className="mt-1 text-[12px] text-ink-3">{totalLabel}</p>
      </div>

      {/* Liste de bénéfices, formulés en valeur (pas en feature spec) */}
      <ul className="relative flex flex-col gap-2.5 text-[13px] text-ink-2 leading-snug mb-7">
        <FeatureLine strong>Factures et relances illimitées</FeatureLine>
        <FeatureLine>OCR sans limite de volume</FeatureLine>
        <FeatureLine>Plans custom + génération IA des relances</FeatureLine>
        <FeatureLine>Mode démo pour montrer l'outil aux prospects</FeatureLine>
        <FeatureLine>Toutes les automatisations</FeatureLine>
      </ul>

      <Button
        size="md"
        variant="primary"
        loading={loading}
        disabled={current}
        onClick={onUpgrade}
        className="relative w-full"
      >
        {current ? (
          "Plan actuel"
        ) : (
          <>
            Passer Pro <ArrowRight size={14} aria-hidden="true" />
          </>
        )}
      </Button>

      <p className="relative mt-3 text-[11px] italic text-ink-3 text-center leading-snug">
        Moins cher qu'une heure de votre temps mensuel.
      </p>
    </Card>
  );
}

// ---------------------------------------------------------------------------
// PlanBusiness — card sobre comme Free mais avec accents rubis-deep.
// ---------------------------------------------------------------------------

function PlanBusiness({
  current,
  cycle,
  loading,
  onUpgrade,
}: {
  current: boolean;
  cycle: BillingCycle;
  loading: boolean;
  onUpgrade: () => void;
}) {
  const monthlyPrice = cycle === "monthly" ? 49 : Math.round((490 / 12) * 100) / 100;
  const totalLabel = cycle === "monthly" ? "facturé chaque mois" : "soit 490 € facturés annuellement";

  return (
    <div className="rounded-card border border-line bg-white p-6 flex flex-col">
      <div className="flex items-baseline gap-2 mb-1">
        <p className="font-display text-[16px] font-bold text-ink">Équipe</p>
        {current && <CurrentBadge />}
      </div>
      <p className="text-[11.5px] uppercase tracking-[0.12em] text-rubis-deep font-semibold mb-5">
        Business
      </p>

      <p className="font-display flex items-baseline mb-1">
        <span className="text-[28px] font-bold tabular-nums tracking-[-0.02em] text-ink leading-none">
          {monthlyPrice.toString().replace(".", ",")} €
        </span>
        <span className="ml-1.5 text-[12px] font-medium text-ink-3">/ mois</span>
      </p>
      <p className="text-[11.5px] text-ink-3 mb-5">{totalLabel}</p>

      <ul className="flex flex-col gap-2.5 text-[12.5px] text-ink-2 leading-snug b-4">
        <FeatureLine strong>Tout Pro, plus :</FeatureLine>
        <FeatureLine>5 sièges utilisateurs</FeatureLine>
        <FeatureLine>Réponses depuis votre email pro</FeatureLine>
        <FeatureLine>Support prioritaire</FeatureLine>
        <FeatureLine subtle>SMS (à venir)</FeatureLine>
      </ul>

      <Button
        size="sm"
        variant="secondary"
        loading={loading}
        disabled={current}
        onClick={onUpgrade}
        className="mt-3 p-6 w-full"
      >
        {current ? (
          "Plan actuel"
        ) : (
          <>
            Passer Business <ArrowRight size={14} aria-hidden="true" />
          </>
        )}
      </Button>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Atomes
// ---------------------------------------------------------------------------

function FeatureLine({
  children,
  strong = false,
  subtle = false,
}: {
  children: React.ReactNode;
  strong?: boolean;
  subtle?: boolean;
}) {
  return (
    <li className="flex items-start gap-2">
      {/* Petit losange rubis = bullet maison cohérent avec la marque */}
      <span
        aria-hidden="true"
        className={cn(
          "mt-1.5 size-[5px] rotate-45 shrink-0",
          subtle ? "bg-ink-3/40" : "bg-rubis",
        )}
      />
      <span
        className={cn(
          strong && "font-semibold text-ink",
          subtle && "text-ink-3 italic",
        )}
      >
        {children}
      </span>
    </li>
  );
}

function CurrentBadge() {
  return (
    <span className="text-[10px] uppercase tracking-[0.14em] font-semibold text-rubis bg-rubis-glow rounded-full px-2 py-0.5">
      Actuel
    </span>
  );
}
