import { useEffect } from "react";
import { useForm } from "@tanstack/react-form";
import { useMutation } from "@tanstack/react-query";
import { Sparkles } from "lucide-react";
import { toast } from "sonner";
import { z } from "zod";

import type { User } from "@rubis/shared";
import { api } from "@/lib/api";
import { authStore, useAuth } from "@/lib/auth";

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

/**
 * Form section "Signature" — apposée à la fin de chaque relance.
 * Réutilise le pattern de l'onboarding step 3 (avec aperçu live).
 */

type FormValues = { signature: string };

const validator = z
  .string()
  .max(500, "500 caractères maximum");

const DEFAULT_SIGNATURE = (fullName: string): string =>
  `Cordialement,\n${fullName}\n— Envoyé via Rubis`;

export function SignatureForm() {
  const { user } = useAuth();

  const updateMutation = useMutation({
    mutationFn: (input: FormValues) =>
      api.patch<User>("/api/v1/account/profile", { signature: input.signature }),
    onSuccess: (updated) => {
      const token = authStore.token;
      if (token) authStore.setSession(token, updated);
      toast.success("Signature mise à jour.");
    },
    onError: () => {
      toast.error("Sauvegarde impossible. Réessayez.");
    },
  });

  const initialSignature =
    user?.signature ?? DEFAULT_SIGNATURE(user?.fullName ?? "Votre nom");

  const form = useForm({
    defaultValues: { signature: initialSignature } satisfies FormValues,
    onSubmit: async ({ value }) => {
      const r = validator.safeParse(value.signature);
      if (!r.success) {
        toast.error(r.error.issues[0]?.message ?? "Signature invalide");
        return;
      }
      await updateMutation.mutateAsync(value);
    },
  });

  useEffect(() => {
    form.reset({ signature: initialSignature });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [user?.id]);

  return (
    <form
      noValidate
      onSubmit={(e) => {
        e.preventDefault();
        void form.handleSubmit();
      }}
      className="flex flex-col gap-5"
    >
      <form.Field name="signature" validators={{ onChange: validator }}>
        {(field) => (
          <>
            <Field
              label="Signature email"
              htmlFor={field.name}
              hint="Markdown léger non interprété. Pas de HTML."
              error={firstError(field.state.meta.errors)}
            >
              <Textarea
                id={field.name}
                rows={5}
                value={field.state.value}
                onChange={(e) => field.handleChange(e.target.value)}
              />
            </Field>

            <Card variant="flat" padding="md">
              <p className="flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-[0.12em] text-ink-3">
                <Sparkles size={12} aria-hidden="true" /> Aperçu dans un email
              </p>
              <pre className="mt-3 whitespace-pre-wrap font-sans text-[14px] leading-relaxed text-ink-2">
                {field.state.value || "(signature vide)"}
              </pre>
            </Card>
          </>
        )}
      </form.Field>

      <div className="flex justify-end">
        <Button
          type="submit"
          size="sm"
          loading={updateMutation.isPending}
          disabled={!form.state.isDirty}
        >
          {form.state.isDirty ? "Enregistrer" : "Aucune modification"}
        </Button>
      </div>
    </form>
  );
}

function firstError(errors: unknown[]): string | undefined {
  const first = errors[0];
  if (!first) return undefined;
  if (typeof first === "string") return first;
  if (typeof first === "object" && first !== null && "message" in first) {
    const msg = (first as { message?: unknown }).message;
    if (typeof msg === "string") return msg;
  }
  return undefined;
}
