import { useEffect, useState } from "react";
import { Mail, ArrowRight, X, Check, AlertCircle, ExternalLink, Calendar, FileText } from "lucide-react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { Link } from "@tanstack/react-router";
import { toast } from "sonner";

import { api } from "@/lib/api";
import { queryKeys } from "@/lib/queryKeys";
import { queryKeysDemo } from "@/lib/demo";
import { cn } from "@/lib/utils";
import { formatEuros, formatDate, formatDueDelta, isOverdue } from "@/lib/format";
import type { DemoCapturedEmail, FiredEvent } from "@/lib/demo";
import { Button } from "@/components/ui/Button";
import { StatusBadge } from "@/components/ui/StatusBadge";

/**
 * Forme minimale du retour `/api/v1/invoices/:id` qu'on consomme.
 * On ne charge pas la timeline ici — pas utile pour le slide démo.
 */
type InvoiceDetail = {
  id: string;
  numero: string;
  clientName: string;
  amountTtcCents: number;
  issueDate: string;
  dueDate: string;
  status:
    | "pending"
    | "in_relance"
    | "awaiting_user_confirmation"
    | "paid"
    | "litigation"
    | "cancelled";
  planName: string | null;
};

/**
 * Slide-over droite — déclenchée à chaque event fired pendant la démo.
 *
 * Flow narratif en 2 étapes :
 *
 *   Étape 1 — "Cette facture a-t-elle été payée ?"
 *      ↓ Oui                    ↓ Non
 *      mark facture paid        on passe à l'étape 2
 *      cancel relances futures  voir l'email envoyé
 *      écran "encaissée"
 *      ↓
 *   Étape 2 — Preview de l'email (Non) OU confirmation paiement (Oui)
 *
 * Le clic sur "Continuer la démo" reprend l'horloge.
 */
const FR_DATETIME = new Intl.DateTimeFormat("fr-FR", {
  weekday: "long",
  day: "numeric",
  month: "long",
});

type Step = "ask" | "email" | "paid";

export function DemoEmailSlide({
  event,
  remaining,
  virtualNow,
  onContinue,
}: {
  event: FiredEvent;
  remaining: number;
  virtualNow: Date;
  onContinue: () => void;
}) {
  const qc = useQueryClient();
  const [step, setStep] = useState<Step>("ask");
  const [email, setEmail] = useState<DemoCapturedEmail | null>(null);
  const [marking, setMarking] = useState(false);

  // Détail de la facture concernée (montant, dates, client, plan).
  const { data: invoice } = useQuery({
    queryKey: queryKeys.invoices.detail(event.invoiceId),
    queryFn: () => api.get<InvoiceDetail>(`/api/v1/invoices/${event.invoiceId}`),
    staleTime: 30_000,
  });

  // Reset à chaque nouvel event
  useEffect(() => {
    setStep("ask");
    setEmail(null);
  }, [event.taskId]);

  // Charge l'email capturé en arrière-plan, pour qu'il soit prêt si on
  // passe à l'étape 'email'.
  useEffect(() => {
    if (!event.capturedEmailId) return;
    let cancelled = false;
    void api
      .get<DemoCapturedEmail[]>("/api/v1/demo/inbox")
      .then((list) => {
        if (cancelled) return;
        const found = list.find((e) => e.id === event.capturedEmailId);
        setEmail(found ?? null);
      })
      .catch(() => setEmail(null));
    return () => {
      cancelled = true;
    };
  }, [event.capturedEmailId]);

  const onMarkPaid = async () => {
    setMarking(true);
    try {
      await api.post(`/api/v1/invoices/${event.invoiceId}/mark-paid`);
      toast.success(`${event.invoiceNumero} marquée encaissée. + 1 rubis.`);
      // Rafraîchit l'écosystème (dashboard, factures, charts) — le user
      // voit la valeur du check-in en direct.
      void qc.invalidateQueries({ queryKey: queryKeys.dashboard.all() });
      void qc.invalidateQueries({ queryKey: queryKeys.invoices.all() });
      void qc.invalidateQueries({ queryKey: queryKeysDemo.state() });
      setStep("paid");
    } catch {
      toast.error("Impossible de marquer la facture payée.");
    } finally {
      setMarking(false);
    }
  };

  const isRelance = event.kind === "relance";

  return (
    <>
      {/* Backdrop cliquable pour fermer */}
      <button
        type="button"
        aria-label="Fermer"
        onClick={onContinue}
        className="fixed inset-0 z-40 bg-ink/35 backdrop-blur-[2px] cursor-default"
      />

      <aside
        role="dialog"
        aria-label="Émission Rubis pendant la démo"
        className={cn(
          "fixed z-50 bg-cream shadow-card flex flex-col",
          // — Mobile : bottom-sheet
          "bottom-0 inset-x-0 max-h-[92vh] rounded-t-[20px] border-t border-line",
          "animate-in slide-in-from-bottom duration-200",
          // — Desktop : slide-over droit
          "sm:bottom-auto sm:inset-x-auto sm:top-0 sm:right-0 sm:h-screen sm:max-h-none",
          "sm:w-full sm:max-w-[520px] sm:rounded-none sm:border-l sm:border-t-0",
          "sm:slide-in-from-right",
        )}
      >
        {/* Drag handle visuel — mobile only, signal "tu peux fermer". */}
        <div
          aria-hidden="true"
          className="sm:hidden mx-auto mt-2.5 mb-1 h-1 w-10 rounded-full bg-ink/15 shrink-0"
        />

        {/* Header — titre adapté à l'event */}
        <div className="flex items-center gap-3 border-b border-line bg-white px-5 py-3.5 shrink-0">
          <span
            className={cn(
              "shrink-0 size-9 flex items-center justify-center rounded-full",
              isRelance ? "bg-rubis text-white" : "bg-rubis-glow text-rubis-deep",
            )}
          >
            <Mail size={15} />
          </span>
          <div className="flex-1 min-w-0">
            <p className="font-display text-[14.5px] font-bold text-ink leading-tight">
              {isRelance ? "Relance" : "Confirmation"} de Facture {event.invoiceNumero}
            </p>
            <p className="text-[11.5px] text-ink-3 capitalize">
              {FR_DATETIME.format(virtualNow)}
            </p>
          </div>
          <button
            type="button"
            onClick={onContinue}
            className={cn(
              "size-8 flex items-center justify-center rounded-default cursor-pointer",
              "text-ink-3 hover:bg-cream-2 hover:text-ink transition-colors",
              "focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-rubis-glow",
            )}
            aria-label="Fermer"
          >
            <X size={16} />
          </button>
        </div>

        {/* Body — change selon l'étape. Padding-bottom safe-area quand pas
            de footer (étape "ask"), sinon le footer s'en occupe. */}
        <div
          className={cn(
            "flex-1 overflow-y-auto px-5 py-5 space-y-5",
            step === "ask" && "pb-[max(1.25rem,env(safe-area-inset-bottom))]",
          )}
        >
          <InvoiceCard
            invoice={invoice ?? null}
            fallbackNumero={event.invoiceNumero}
            onNavigate={onContinue}
          />

          {step === "ask" && (
            <AskStep
              isRelance={isRelance}
              marking={marking}
              onYes={onMarkPaid}
              onNo={() => setStep("email")}
            />
          )}
          {step === "email" && <EmailStep email={email} />}
          {step === "paid" && <PaidStep invoiceNumero={event.invoiceNumero} />}
        </div>

        {/* Footer — uniquement à l'étape email/paid (l'étape ask a ses propres boutons).
            Padding inférieur safe-area pour les iPhones notchés. */}
        {step !== "ask" && (
          <div
            className={cn(
              "border-t border-line bg-white px-5 py-4 shrink-0",
              "flex items-center justify-between gap-3",
              "pb-[max(1rem,env(safe-area-inset-bottom))]",
            )}
          >
            <p className="text-[11.5px] text-ink-3 italic min-w-0">
              {remaining > 0
                ? `${remaining} autre${remaining > 1 ? "s" : ""} event${remaining > 1 ? "s" : ""} en file`
                : "Cliquez pour reprendre l'horloge"}
            </p>
            <Button size="sm" onClick={onContinue} className="shrink-0">
              Continuer <ArrowRight size={14} />
            </Button>
          </div>
        )}
      </aside>
    </>
  );
}

/** Étape 1 — la question. */
function AskStep({
  isRelance,
  marking,
  onYes,
  onNo,
}: {
  isRelance: boolean;
  marking: boolean;
  onYes: () => void;
  onNo: () => void;
}) {
  return (
    <div className="flex flex-col items-start gap-4">
      <div>
        <p className="text-[10.5px] uppercase tracking-[0.12em] text-rubis font-semibold mb-2">
          Avant d'envoyer
        </p>
        <h3 className="font-display text-[22px] font-bold tracking-[-0.018em] text-ink leading-tight">
          Avez-vous été payé sur cette facture ?
        </h3>
        <p className="mt-2 text-[13px] text-ink-2 leading-relaxed">
          {isRelance
            ? "Rubis est sur le point de relancer votre client. Si la facture vient d'être réglée, on évite l'email inutile et on encaisse +1 rubis."
            : "Rubis s'apprête à vous demander confirmation. Si vous savez déjà qu'elle est payée, on saute cette étape."}
        </p>
      </div>

      <div className="flex flex-col gap-2.5 w-full">
        <Button
          size="md"
          variant="primary"
          loading={marking}
          onClick={onYes}
          className="w-full justify-start"
        >
          <Check size={15} aria-hidden="true" />
          Oui — la facture est payée
        </Button>
        <Button
          size="md"
          variant="secondary"
          onClick={onNo}
          className="w-full justify-start"
        >
          <AlertCircle size={15} aria-hidden="true" />
          Non — toujours en attente
        </Button>
      </div>

      <p className="text-[11.5px] text-ink-3 italic leading-snug">
        En conditions réelles, l'email de confirmation pose cette question au
        client final. Ici on raccourcit pour la démo.
      </p>
    </div>
  );
}

/**
 * Card de contexte facture — visible en permanence dans le slide-over.
 * Cliquable : ouvre la fiche facture dans la vraie app (ferme la slide,
 * l'horloge reste en pause pour qu'on puisse revenir).
 */
function InvoiceCard({
  invoice,
  fallbackNumero,
  onNavigate,
}: {
  invoice: InvoiceDetail | null;
  fallbackNumero: string;
  onNavigate: () => void;
}) {
  if (!invoice) {
    return (
      <div className="rounded-card border border-line bg-white px-4 py-3">
        <p className="text-[12px] text-ink-3 italic">
          Chargement de la facture {fallbackNumero}…
        </p>
      </div>
    );
  }

  const dueLabel = formatDueDelta(invoice.dueDate);
  const isLate = isOverdue(invoice.dueDate) && invoice.status !== "paid";

  return (
    <Link
      to="/factures/$id"
      params={{ id: invoice.id }}
      onClick={onNavigate}
      className={cn(
        "block rounded-card border border-line bg-white px-4 py-3.5",
        "transition-[border-color,box-shadow,transform] duration-150",
        "hover:border-rubis hover:shadow-soft hover:-translate-y-px",
        "focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-rubis-glow",
      )}
      aria-label={`Voir la fiche de la facture ${invoice.numero}`}
    >
      {/* Header : numéro + statut + flèche externe */}
      <div className="flex items-start justify-between gap-3 mb-3">
        <div className="min-w-0 flex-1">
          <div className="flex items-center gap-2 mb-0.5">
            <FileText size={13} className="text-ink-3 shrink-0" aria-hidden="true" />
            <p className="font-display text-[14px] font-semibold tracking-tight text-ink truncate">
              {invoice.numero}
            </p>
          </div>
          <p className="text-[12.5px] text-ink-2 truncate">{invoice.clientName}</p>
        </div>
        <div className="flex items-center gap-2 shrink-0">
          <StatusBadge status={invoice.status} withoutIcon />
          <ExternalLink size={13} className="text-ink-3" aria-hidden="true" />
        </div>
      </div>

      {/* Montant en gros + dates */}
      <div className="flex items-end justify-between gap-3">
        <p className="font-display text-[22px] font-bold tabular-nums leading-none text-ink">
          {formatEuros(invoice.amountTtcCents)}
        </p>
        <div className="text-right">
          <div className="flex items-center gap-1 justify-end text-[11.5px] text-ink-3 tabular-nums">
            <Calendar size={11} aria-hidden="true" />
            <span>
              Émise {formatDate(invoice.issueDate)} · échue{" "}
              {formatDate(invoice.dueDate)}
            </span>
          </div>
          <p
            className={cn(
              "mt-0.5 text-[11.5px] font-medium tabular-nums",
              isLate ? "text-rubis-deep" : "text-ink-3",
            )}
          >
            {dueLabel}
          </p>
        </div>
      </div>

      {invoice.planName && (
        <p className="mt-3 pt-3 border-t border-line text-[11.5px] text-ink-3">
          Plan : <strong className="font-medium text-ink-2">{invoice.planName}</strong>
        </p>
      )}
    </Link>
  );
}

/** Étape 2A — preview de l'email envoyé (réponse "Non"). */
function EmailStep({ email }: { email: DemoCapturedEmail | null }) {
  if (!email) {
    return (
      <p className="text-[13px] italic text-ink-3 text-center py-8">
        Chargement de l'email…
      </p>
    );
  }
  return (
    <article className="rounded-card border border-line bg-white shadow-soft overflow-hidden">
      <div className="border-b border-line bg-cream-2/50 px-5 py-3 space-y-1">
        <p className="text-[11.5px] text-ink-3">
          <span className="font-semibold text-ink-2">De :</span>{" "}
          {email.from.name} &lt;{email.from.email}&gt;
        </p>
        <p className="text-[11.5px] text-ink-3">
          <span className="font-semibold text-ink-2">À :</span>{" "}
          {email.to.name ? `${email.to.name} — ` : ""}
          {email.to.email}
        </p>
        {email.replyTo && (
          <p className="text-[11.5px] text-ink-3">
            <span className="font-semibold text-ink-2">Reply-To :</span>{" "}
            {email.replyTo}
          </p>
        )}
        <p className="font-display text-[15px] font-bold text-ink mt-1.5 leading-tight">
          {email.subject}
        </p>
      </div>
      <div className="px-5 py-4">
        <pre className="whitespace-pre-wrap font-sans text-[13.5px] leading-relaxed text-ink-2">
          {email.body}
        </pre>
      </div>
    </article>
  );
}

/** Étape 2B — confirmation paiement (réponse "Oui"). */
function PaidStep({ invoiceNumero }: { invoiceNumero: string }) {
  return (
    <div className="flex flex-col items-start gap-4 py-4">
      <div className="size-12 rounded-full bg-rubis-glow flex items-center justify-center text-rubis-deep">
        <Check size={22} strokeWidth={2.5} aria-hidden="true" />
      </div>
      <div>
        <p className="text-[10.5px] uppercase tracking-[0.12em] text-rubis font-semibold mb-1">
          Encaissée
        </p>
        <h3 className="font-display text-[22px] font-bold tracking-[-0.018em] text-ink leading-tight">
          Facture <em className="text-rubis not-italic">{invoiceNumero}</em>{" "}
          marquée payée
        </h3>
        <p className="mt-3 text-[13.5px] text-ink-2 leading-relaxed">
          Les relances futures de cette facture sont annulées
          automatiquement. Pas d'email inutile envoyé à votre client.
          Vous gagnez{" "}
          <strong className="text-rubis-deep">+1 rubis</strong> pour les 10 minutes
          que Rubis vient de vous économiser.
        </p>
      </div>
      <p className="text-[11.5px] text-ink-3 italic leading-snug">
        Regardez le dashboard derrière : le compteur a déjà bougé.
      </p>
    </div>
  );
}
