import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useForm } from "@tanstack/react-form";
import { useMutation } from "@tanstack/react-query";
import { ArrowRight } 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 { Input } from "@/components/ui/Input";
import { Field } from "@/components/ui/Field";
import { Eyebrow } from "@/components/ui/Eyebrow";

const accountSchema = z.object({
  fullName: z
    .string({ required_error: "Votre prénom et nom" })
    .min(2, "Au moins 2 caractères"),
  email: z
    .string({ required_error: "Votre email est requis" })
    .email("Format d'email invalide"),
});

type AccountInput = z.infer<typeof accountSchema>;

export const Route = createFileRoute("/onboarding/compte")({
  component: OnboardingCompte,
});

function OnboardingCompte() {
  const navigate = useNavigate();
  const { user } = useAuth();

  const updateProfile = useMutation({
    mutationFn: async (input: AccountInput) =>
      api.patch<User>("/api/v1/account/profile", input),
    onSuccess: (updatedUser) => {
      // On garde le token courant, on rafraîchit juste le user.
      const token = authStore.token;
      if (token) authStore.setSession(token, updatedUser);
      void navigate({ to: "/onboarding/entreprise" });
    },
    onError: () => {
      toast.error("On n'a pas pu enregistrer. Réessayez dans un instant.");
    },
  });

  const form = useForm({
    defaultValues: {
      fullName: user?.fullName ?? "",
      email: user?.email ?? "",
    } satisfies AccountInput,
    validators: { onChange: accountSchema },
    onSubmit: async ({ value }) => {
      await updateProfile.mutateAsync(value);
    },
  });

  return (
    <div>
      <Eyebrow>Étape 1</Eyebrow>
      <h1 className="mt-3 font-display text-[34px] font-bold leading-[1.1] tracking-[-0.022em] text-ink">
        Vous, en <em>deux lignes</em>.
      </h1>
      <p className="mt-3 max-w-md text-[15px] leading-relaxed text-ink-2">
        Ce qui apparaîtra sur les emails de relance que Rubis enverra pour
        vous. Modifiable plus tard depuis vos paramètres.
      </p>

      <form
        noValidate
        onSubmit={(e) => {
          e.preventDefault();
          void form.handleSubmit();
        }}
        className="mt-10 flex flex-col gap-5"
      >
        <form.Field name="fullName">
          {(field) => (
            <Field
              label="Prénom et nom"
              htmlFor={field.name}
              error={field.state.meta.errors[0]?.message}
            >
              <Input
                id={field.name}
                name={field.name}
                type="text"
                autoComplete="name"
                autoFocus
                value={field.state.value}
                onBlur={field.handleBlur}
                onChange={(e) => field.handleChange(e.target.value)}
                aria-invalid={field.state.meta.errors.length > 0}
              />
            </Field>
          )}
        </form.Field>

        <form.Field name="email">
          {(field) => (
            <Field
              label="Email"
              htmlFor={field.name}
              hint="Adresse expéditrice des relances. Évitez les boîtes nominatives ('paul@'), préférez 'compta@'."
              error={field.state.meta.errors[0]?.message}
            >
              <Input
                id={field.name}
                name={field.name}
                type="email"
                autoComplete="email"
                value={field.state.value}
                onBlur={field.handleBlur}
                onChange={(e) => field.handleChange(e.target.value)}
                aria-invalid={field.state.meta.errors.length > 0}
              />
            </Field>
          )}
        </form.Field>

        <div className="mt-3 flex justify-end">
          <Button type="submit" loading={updateProfile.isPending}>
            Continuer <ArrowRight size={16} aria-hidden="true" />
          </Button>
        </div>
      </form>
    </div>
  );
}
