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

import {
  MONTHLY_VOLUME_BUCKETS,
  type Organization,
} from "@rubis/shared";
import { api } from "@/lib/api";

import { Button } from "@/components/ui/Button";
import { Field } from "@/components/ui/Field";
import { Input } from "@/components/ui/Input";
import { Chip } from "@/components/ui/Chip";

/**
 * Form section "Entreprise" — nom, SIRET, volume mensuel.
 * Réutilise le pattern des chips volume de l'onboarding step 2.
 */

const VOLUME_LABELS: Record<(typeof MONTHLY_VOLUME_BUCKETS)[number], string> = {
  "moins-10": "Moins de 10",
  "10-50": "10 à 50",
  "50-100": "50 à 100",
  "100-200": "100 à 200",
  "plus-200": "Plus de 200",
};

type VolumeBucket = (typeof MONTHLY_VOLUME_BUCKETS)[number];

type FormValues = {
  name: string;
  siret: string;
  monthlyVolumeBucket: VolumeBucket;
};

const validators = {
  name: z.string().min(2, "Au moins 2 caractères").max(120),
  siret: z
    .string()
    .refine(
      (v) => v === "" || /^\d{14}$/u.test(v),
      "14 chiffres exactement (ou laissez vide)",
    ),
};

const ORG_QUERY_KEY = ["organization", "me"] as const;

export function OrganizationForm() {
  const queryClient = useQueryClient();

  const { data: org } = useQuery({
    queryKey: ORG_QUERY_KEY,
    queryFn: () => api.get<Organization>("/api/v1/organizations/me"),
  });

  const updateMutation = useMutation({
    mutationFn: (input: FormValues) =>
      api.patch<Organization>("/api/v1/organizations/me", {
        name: input.name.trim(),
        siret: input.siret.trim() === "" ? null : input.siret.trim(),
        monthlyVolumeBucket: input.monthlyVolumeBucket,
      }),
    onSuccess: (updated) => {
      queryClient.setQueryData(ORG_QUERY_KEY, updated);
      toast.success("Entreprise mise à jour.");
    },
    onError: () => {
      toast.error("Sauvegarde impossible. Réessayez.");
    },
  });

  const initialValues: FormValues = {
    name: org?.name ?? "",
    siret: org?.siret ?? "",
    monthlyVolumeBucket: (org?.monthlyVolumeBucket ?? "10-50") as VolumeBucket,
  };

  const form = useForm({
    defaultValues: initialValues,
    onSubmit: async ({ value }) => {
      const nameCheck = validators.name.safeParse(value.name);
      if (!nameCheck.success) {
        toast.error(nameCheck.error.issues[0]?.message ?? "Nom invalide");
        return;
      }
      const siretCheck = validators.siret.safeParse(value.siret);
      if (!siretCheck.success) {
        toast.error(siretCheck.error.issues[0]?.message ?? "SIRET invalide");
        return;
      }
      await updateMutation.mutateAsync(value);
    },
  });

  // Sync quand le serveur renvoie les données (premier render = org undefined)
  useEffect(() => {
    if (org) form.reset(initialValues);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [org?.id, org?.updatedAt]);

  return (
    <form
      noValidate
      onSubmit={(e) => {
        e.preventDefault();
        void form.handleSubmit();
      }}
      className="flex flex-col gap-5"
    >
      <form.Field name="name" validators={{ onChange: validators.name }}>
        {(field) => (
          <Field
            label="Nom de l'entreprise"
            htmlFor={field.name}
            hint="Apparaît dans les emails de relance envoyés à vos clients."
            error={firstError(field.state.meta.errors)}
          >
            <Input
              id={field.name}
              value={field.state.value}
              onChange={(e) => field.handleChange(e.target.value)}
            />
          </Field>
        )}
      </form.Field>

      <form.Field name="siret" validators={{ onChange: validators.siret }}>
        {(field) => (
          <Field
            label="SIRET"
            htmlFor={field.name}
            hint="14 chiffres. Nécessaire pour les mises en demeure formelles."
            error={firstError(field.state.meta.errors)}
          >
            <Input
              id={field.name}
              type="text"
              inputMode="numeric"
              autoComplete="off"
              placeholder="123 456 789 00012"
              value={field.state.value}
              onChange={(e) =>
                field.handleChange(e.target.value.replace(/\s/gu, ""))
              }
            />
          </Field>
        )}
      </form.Field>

      <form.Field name="monthlyVolumeBucket">
        {(field) => (
          <fieldset>
            <legend className="font-sans text-[13px] font-semibold text-ink mb-2">
              Volume mensuel de factures
            </legend>
            <p className="mb-3 text-[12.5px] text-ink-3 leading-snug">
              Sert juste à proposer le bon plan tarifaire par défaut.
              Modifiable n&apos;importe quand.
            </p>
            <div className="flex flex-wrap gap-2">
              {MONTHLY_VOLUME_BUCKETS.map((bucket) => (
                <Chip
                  key={bucket}
                  selected={field.state.value === bucket}
                  onClick={() => field.handleChange(bucket)}
                >
                  {VOLUME_LABELS[bucket]}
                </Chip>
              ))}
            </div>
          </fieldset>
        )}
      </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;
}
