import { useState, useEffect } from "react";
import { useMutation } from "@tanstack/react-query";
import { Sparkles, RefreshCw, Info } from "lucide-react";
import { toast } from "sonner";
import type { RelanceTone } from "@rubis/shared";

import { api } from "@/lib/api";
import { TONE_LABELS, TEMPLATE_VARIABLES } from "@/lib/plans";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogFooter,
  DialogClose,
} from "@/components/ui/Dialog";
import { Button } from "@/components/ui/Button";
import { Field } from "@/components/ui/Field";
import { Textarea } from "@/components/ui/Textarea";
import { EmailPreview } from "./EmailPreview";

type GenerateResult = { subject: string; body: string };

const DEFAULT_PROMPTS: Record<RelanceTone, string> = {
  amical:
    "Premier rappel chaleureux, pas de pression. Si possible, mentionne qu'on accepte les virements et qu'on reste dispo.",
  courtois:
    "Relance standard B2B, factuelle, polie mais directe. Demande un règlement dans les meilleurs délais.",
  ferme:
    "Relance ferme : on a déjà relancé plusieurs fois, on attend le règlement sous 8 jours avant la mise en demeure.",
  mise_en_demeure:
    "Mise en demeure formelle. Mentionne le délai de 8 jours, les pénalités de retard, l'indemnité forfaitaire de 40€, et la possibilité d'engager une procédure judiciaire.",
};

/**
 * Modale qui appelle l'IA pour générer le subject + body d'une étape.
 * Le contexte envoyé à Mistral inclut : nom + description du plan parent,
 * tonalité + timing de la relance, brief de l'utilisateur, et la liste
 * des variables disponibles (pas obligées d'être utilisées toutes).
 */
export function AiGenerateModal({
  open,
  onOpenChange,
  tone,
  offsetDays,
  planName,
  planDescription,
  onAccept,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  tone: RelanceTone;
  offsetDays: number;
  planName?: string;
  planDescription?: string;
  onAccept: (result: GenerateResult) => void;
}) {
  const [prompt, setPrompt] = useState(DEFAULT_PROMPTS[tone]);
  const [result, setResult] = useState<GenerateResult | null>(null);

  useEffect(() => {
    if (open) {
      setPrompt(DEFAULT_PROMPTS[tone]);
      setResult(null);
    }
  }, [open, tone]);

  const generateMutation = useMutation({
    mutationFn: () =>
      api.post<GenerateResult>("/api/v1/ai/generate-relance", {
        tone,
        offsetDays,
        prompt,
        planName,
        planDescription,
      }),
    onSuccess: (data) => setResult(data),
    onError: () => toast.error("Génération impossible. Réessayez dans un instant."),
  });

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent maxWidth={720}>
        <DialogHeader>
          <DialogTitle>
            <span className="inline-flex items-center gap-2 border border-rubis">
              <Sparkles size={16} className="text-rubis" /> Générer avec l'IA
            </span>
          </DialogTitle>
          <DialogDescription>
            Pour le plan{" "}
            <strong className="text-ink-2">{planName || "(sans nom)"}</strong>,
            l'IA va rédiger une relance de tonalité{" "}
            <strong>{TONE_LABELS[tone].toLowerCase()}</strong> programmée J
            {offsetDays >= 0 ? "+" : ""}
            {offsetDays}. Affinez le brief si besoin.
          </DialogDescription>
        </DialogHeader>

        <div className="flex flex-col gap-5">
          <Field
            label="Brief pour l'IA"
            htmlFor="ai-prompt"
            hint="Ce que vous voulez transmettre. Plus c'est précis, mieux c'est."
          >
            <Textarea
              id="ai-prompt"
              rows={3}
              value={prompt}
              onChange={(e) => setPrompt(e.target.value)}
              placeholder="Ex. Relance amicale, on accepte les virements, le client est de longue date…"
            />
          </Field>

          <details className="rounded-default border border-line bg-cream-2/40 px-3 py-2">
            <summary className="cursor-pointer flex items-center gap-1.5 text-[12px] font-semibold text-ink-2 list-none">
              <Info size={12} className="text-ink-3" />
              Variables que l'IA peut insérer (sans obligation)
            </summary>
            <ul className="mt-2 grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-0.5 text-[11.5px] text-ink-3">
              {TEMPLATE_VARIABLES.map((v) => (
                <li key={v.token} className="truncate">
                  <code className="font-mono text-[11px] text-rubis-deep">
                    {v.token}
                  </code>{" "}
                  · {v.label}
                </li>
              ))}
            </ul>
            <p className="mt-2 text-[11px] text-ink-3 italic leading-snug">
              L'IA en utilisera une partie selon le sens du message — pas toutes.
              {" "}
              <strong className="text-ink-2">{`{{signature}}`}</strong> est
              automatiquement ajouté en fin de corps.
            </p>
          </details>

          {result && (
            <div className="space-y-2">
              <p className="text-[11px] uppercase tracking-[0.1em] text-ink-3 font-semibold">
                Résultat
              </p>
              <EmailPreview subject={result.subject} body={result.body} />
            </div>
          )}
        </div>

        <DialogFooter>
          <DialogClose asChild>
            <Button variant="secondary" size="sm" type="button">
              Annuler
            </Button>
          </DialogClose>
          {result ? (
            <>
              <Button
                variant="ghost"
                size="sm"
                type="button"
                onClick={() => generateMutation.mutate()}
                loading={generateMutation.isPending}
              >
                <RefreshCw size={13} /> Régénérer
              </Button>
              <Button
                size="sm"
                type="button"
                onClick={() => {
                  onAccept(result);
                  onOpenChange(false);
                }}
              >
                Utiliser ce message
              </Button>
            </>
          ) : (
            <Button
              size="sm"
              type="button"
              onClick={() => generateMutation.mutate()}
              loading={generateMutation.isPending}
            >
              <Sparkles size={13} /> Générer
            </Button>
          )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
