"use client";

import { useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { signOut } from "next-auth/react";
import { CheckCircle2, Loader2, LogOut } from "lucide-react";
import { DIABETES_TYPE_OPTIONS, SEX_OPTIONS } from "@/lib/patient";

type PatientInput = {
  firstName: string;
  lastName: string;
  email: string | null;
  birthDate: string | null;
  heightCm: number | null;
  weightKg: number | null;
  sex: string | null;
  diabetesType: string | null;
  treatment: string | null;
};

export function ProfileForm({ initial }: { initial: PatientInput | null }) {
  const router = useRouter();
  const [form, setForm] = useState<PatientInput>(() => ({
    firstName: initial?.firstName ?? "",
    lastName: initial?.lastName ?? "",
    email: initial?.email ?? "",
    birthDate: initial?.birthDate ?? "",
    heightCm: initial?.heightCm ?? null,
    weightKg: initial?.weightKg ?? null,
    sex: initial?.sex ?? null,
    diabetesType: initial?.diabetesType ?? null,
    treatment: initial?.treatment ?? "",
  }));
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState(false);

  const bmi = useMemo(() => {
    if (!form.heightCm || !form.weightKg) return null;
    const m = form.heightCm / 100;
    return form.weightKg / (m * m);
  }, [form.heightCm, form.weightKg]);

  const age = useMemo(() => {
    if (!form.birthDate) return null;
    const d = new Date(form.birthDate);
    if (Number.isNaN(d.getTime())) return null;
    const now = new Date();
    let a = now.getFullYear() - d.getFullYear();
    const m = now.getMonth() - d.getMonth();
    if (m < 0 || (m === 0 && now.getDate() < d.getDate())) a--;
    return a;
  }, [form.birthDate]);

  function update<K extends keyof PatientInput>(key: K, value: PatientInput[K]) {
    setForm((f) => ({ ...f, [key]: value }));
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setError(null);
    setSuccess(false);

    if (!form.firstName.trim() || !form.lastName.trim()) {
      setError("Le nom et le prénom sont obligatoires.");
      return;
    }

    setSubmitting(true);
    try {
      const res = await fetch("/api/patient", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          firstName: form.firstName.trim(),
          lastName: form.lastName.trim(),
          email: form.email?.trim() || null,
          birthDate: form.birthDate || null,
          heightCm: form.heightCm,
          weightKg: form.weightKg,
          sex: form.sex || null,
          diabetesType: form.diabetesType || null,
          treatment: form.treatment?.trim() || null,
        }),
      });
      if (!res.ok) {
        const data = await res.json().catch(() => ({}));
        throw new Error(data.error ?? "Erreur lors de l'enregistrement.");
      }
      setSuccess(true);
      router.refresh();
      setTimeout(() => setSuccess(false), 2500);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Erreur inconnue");
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <form
      onSubmit={handleSubmit}
      className="space-y-5 rounded-xl border border-slate-200 bg-white p-5 shadow-sm"
    >
      <div className="grid gap-4 sm:grid-cols-2">
        <Field label="Prénom" required>
          <input
            type="text"
            value={form.firstName}
            onChange={(e) => update("firstName", e.target.value)}
            className={inputClass}
            autoComplete="given-name"
          />
        </Field>
        <Field label="Nom" required>
          <input
            type="text"
            value={form.lastName}
            onChange={(e) => update("lastName", e.target.value)}
            className={inputClass}
            autoComplete="family-name"
          />
        </Field>
      </div>

      <Field label="Email">
        <input
          type="email"
          value={form.email ?? ""}
          onChange={(e) => update("email", e.target.value)}
          className={inputClass}
          autoComplete="email"
          placeholder="prenom.nom@exemple.fr"
        />
      </Field>

      <Field
        label="Date de naissance"
        hint={age !== null ? `${age} ans` : undefined}
      >
        <input
          type="date"
          value={form.birthDate ?? ""}
          onChange={(e) => update("birthDate", e.target.value)}
          className={inputClass}
        />
      </Field>

      <div className="grid gap-4 sm:grid-cols-2">
        <Field label="Taille (cm)">
          <input
            type="number"
            inputMode="numeric"
            min={50}
            max={260}
            value={form.heightCm ?? ""}
            onChange={(e) =>
              update("heightCm", e.target.value === "" ? null : Number(e.target.value))
            }
            className={inputClass}
            placeholder="175"
          />
        </Field>
        <Field label="Poids (kg)">
          <input
            type="number"
            inputMode="decimal"
            min={20}
            max={400}
            step={0.1}
            value={form.weightKg ?? ""}
            onChange={(e) =>
              update("weightKg", e.target.value === "" ? null : Number(e.target.value))
            }
            className={inputClass}
            placeholder="72,5"
          />
        </Field>
      </div>

      <div className="border-t border-slate-200 pt-5">
        <h2 className="mb-4 text-sm font-semibold uppercase tracking-wide text-slate-500">
          Profil médical
        </h2>

        <div className="grid gap-4 sm:grid-cols-2">
          <Field label="Sexe">
            <select
              value={form.sex ?? ""}
              onChange={(e) => update("sex", e.target.value || null)}
              className={inputClass}
            >
              <option value="">—</option>
              {SEX_OPTIONS.map((o) => (
                <option key={o.value} value={o.value}>
                  {o.label}
                </option>
              ))}
            </select>
          </Field>
          <Field label="Type de diabète">
            <select
              value={form.diabetesType ?? ""}
              onChange={(e) => update("diabetesType", e.target.value || null)}
              className={inputClass}
            >
              <option value="">—</option>
              {DIABETES_TYPE_OPTIONS.map((o) => (
                <option key={o.value} value={o.value}>
                  {o.label}
                </option>
              ))}
            </select>
          </Field>
        </div>

        <div className="mt-4">
          <Field
            label="Traitement en cours"
            hint="Ex. Metformine 1000 mg matin et soir, insuline lente le soir…"
          >
            <textarea
              rows={4}
              value={form.treatment ?? ""}
              onChange={(e) => update("treatment", e.target.value)}
              className={inputClass}
              placeholder="Médicaments, posologies, insulinothérapie…"
              maxLength={1000}
            />
          </Field>
        </div>
      </div>

      {bmi !== null && (
        <div className="rounded-md border border-slate-200 bg-slate-50 px-3 py-2 text-sm text-slate-700">
          IMC&nbsp;: <span className="font-semibold">{bmi.toFixed(1)}</span>{" "}
          <span className="text-slate-500">({bmiLabel(bmi)})</span>
        </div>
      )}

      {error && (
        <div className="rounded-md border border-rose-300 bg-rose-50 px-3 py-2 text-sm text-rose-800">
          {error}
        </div>
      )}
      {success && (
        <div className="flex items-center gap-2 rounded-md border border-emerald-300 bg-emerald-50 px-3 py-2 text-sm text-emerald-800">
          <CheckCircle2 className="h-4 w-4" />
          Fiche enregistrée.
        </div>
      )}

      <div className="flex gap-3">
        <button
          type="submit"
          disabled={submitting}
          className="flex-1 inline-flex items-center justify-center gap-2 rounded-lg bg-teal-600 px-4 py-3 text-sm font-medium text-white shadow-sm hover:bg-teal-700 disabled:cursor-not-allowed disabled:opacity-60"
        >
          {submitting ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
          Enregistrer
        </button>
        <button
          type="button"
          onClick={() => signOut({ callbackUrl: "/" })}
          className="inline-flex items-center justify-center gap-2 rounded-lg border border-slate-300 bg-white px-4 py-3 text-sm font-medium text-slate-700 shadow-sm hover:bg-slate-50"
          title="Se déconnecter"
        >
          <LogOut className="h-4 w-4" />
          <span className="hidden sm:inline">Déconnexion</span>
        </button>
      </div>
    </form>
  );
}

const inputClass =
  "w-full rounded-lg border border-slate-300 bg-white px-3 py-2 outline-none focus:border-teal-500 focus:ring-2 focus:ring-teal-200";

function Field({
  label,
  hint,
  required,
  children,
}: {
  label: string;
  hint?: string;
  required?: boolean;
  children: React.ReactNode;
}) {
  return (
    <div>
      <label className="mb-1.5 flex items-baseline justify-between text-sm font-medium text-slate-700">
        <span>
          {label}
          {required && <span className="ml-0.5 text-rose-600">*</span>}
        </span>
        {hint && <span className="text-xs font-normal text-slate-500">{hint}</span>}
      </label>
      {children}
    </div>
  );
}

function bmiLabel(bmi: number) {
  if (bmi < 18.5) return "insuffisance pondérale";
  if (bmi < 25) return "corpulence normale";
  if (bmi < 30) return "surpoids";
  if (bmi < 35) return "obésité modérée";
  if (bmi < 40) return "obésité sévère";
  return "obésité morbide";
}
