"use client"

import {
  useState,
  useEffect,
  useId,
  forwardRef,
  useCallback,
  useRef,
  type InputHTMLAttributes,
} from "react"
import { useForm, useFieldArray, Controller } from "react-hook-form"
import { z } from "zod"
import { zodResolver } from "@hookform/resolvers/zod"
import {
  Star,
  X,
  User,
  Building2,
  Mail,
  Phone,
  MapPin,
  Cake,
  FileText,
  Plus,
  ChevronDown,
  ChevronUp,
  Check,
} from "lucide-react"
import { Button } from "@/components/ui/button"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover"
import { useContactsStore } from "@/lib/contacts/contacts-store"
import { useContactsList } from "@/lib/contacts/use-contacts-list"
import { useCreateContact, useUpdateContact } from "@/lib/api/hooks/use-contact-mutations"
import { fullContactToApiContact } from "@/lib/api/adapters"
import { fullContactDisplayName, type FullContact } from "@/lib/contacts/types"
import { avatarColor, senderInitial } from "@/lib/sender-display"
import { useNavStore } from "@/lib/stores/nav-store"
import {
  CONTACTS_PANEL_ADD_TAG_BTN_CLASS,
  CONTACTS_PANEL_AVATAR_PLACEHOLDER_CLASS,
  CONTACTS_PANEL_CARD_CLASS,
  CONTACTS_PANEL_FLOATING_INPUT_CLASS,
  CONTACTS_PANEL_FLOATING_LABEL_CLASS,
  CONTACTS_PANEL_FLOATING_TEXTAREA_CLASS,
  CONTACTS_PANEL_HEADER_CLASS,
  CONTACTS_PANEL_ICON_BTN_CLASS,
  CONTACTS_PANEL_LINK_TEXT_CLASS,
  CONTACTS_PANEL_MUTED_ICON_CLASS,
  CONTACTS_PANEL_POPOVER_ITEM_CLASS,
  CONTACTS_PANEL_SAVE_BTN_CLASS,
  CONTACTS_PANEL_SELECT_TRIGGER_CLASS,
  CONTACTS_PANEL_SHELL_CLASS,
  CONTACTS_PANEL_TAG_CLASS,
  CONTACTS_MUTED_TEXT,
} from "@/lib/contacts-chrome-classes"
import { cn } from "@/lib/utils"
import { ContactsPanelLogo } from "./contacts-panel-logo"

const FRENCH_MONTHS = [
  "Janvier", "Février", "Mars", "Avril", "Mai", "Juin",
  "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre",
] as const

const EMAIL_LABELS = ["Domicile", "Travail", "Autre"] as const
const PHONE_LABELS = ["Mobile", "Domicile", "Travail"] as const
const ADDRESS_LABELS = ["Domicile", "Travail", "Autre"] as const

const addressSchema = z.object({
  street: z.string().optional().default(""),
  city: z.string().optional().default(""),
  region: z.string().optional().default(""),
  postalCode: z.string().optional().default(""),
  country: z.string().optional().default(""),
  label: z.string().default("Domicile"),
})

const contactFormSchema = z.object({
  namePrefix: z.string().optional().default(""),
  firstName: z.string().optional().default(""),
  middleName: z.string().optional().default(""),
  lastName: z.string().optional().default(""),
  nameSuffix: z.string().optional().default(""),
  phoneticFirstName: z.string().optional().default(""),
  phoneticLastName: z.string().optional().default(""),
  company: z.string().optional().default(""),
  department: z.string().optional().default(""),
  jobTitle: z.string().optional().default(""),
  emails: z.array(
    z.object({
      value: z.string(),
      label: z.string(),
    }),
  ),
  phones: z.array(
    z.object({
      value: z.string(),
      label: z.string(),
    }),
  ),
  addresses: z.array(addressSchema),
  birthday: z
    .object({
      day: z.any().optional(),
      month: z.any().optional(),
      year: z.any().optional(),
    })
    .optional(),
  notes: z.string().optional().default(""),
  labels: z.array(z.string()).optional().default([]),
})

type ContactFormValues = z.infer<typeof contactFormSchema>

interface ContactFormViewProps {
  mode: "create" | "edit"
  contactId?: string | null
}

export function ContactFormView({ mode, contactId }: ContactFormViewProps) {
  const {
    setView,
    showContactsList,
    closePanel,
    createDraft,
    clearCreateDraft,
  } = useContactsStore()
  const { contacts, bookId } = useContactsList()
  const createContactMutation = useCreateContact()
  const updateContactMutation = useUpdateContact()
  const labelRows = useNavStore((s) => s.labelRows)
  const [starred, setStarred] = useState(false)
  const [nameExpanded, setNameExpanded] = useState(false)
  const [companyExpanded, setCompanyExpanded] = useState(false)

  const existingContact =
    mode === "edit" ? contacts.find((c) => c.id === contactId) : null

  const {
    register,
    handleSubmit,
    control,
    watch,
    reset,
    setValue,
    formState: { isDirty },
  } = useForm<ContactFormValues>({
    resolver: zodResolver(contactFormSchema),
    defaultValues: {
      namePrefix: "",
      firstName: "",
      middleName: "",
      lastName: "",
      nameSuffix: "",
      phoneticFirstName: "",
      phoneticLastName: "",
      company: "",
      department: "",
      jobTitle: "",
      emails: [{ value: "", label: "Domicile" }],
      phones: [{ value: "", label: "Mobile" }],
      addresses: [],
      birthday: { day: undefined, month: undefined, year: undefined },
      notes: "",
      labels: [],
    },
  })

  const {
    fields: emailFields,
    append: appendEmail,
    remove: removeEmail,
  } = useFieldArray({ control, name: "emails" })

  const {
    fields: phoneFields,
    append: appendPhone,
    remove: removePhone,
  } = useFieldArray({ control, name: "phones" })

  const {
    fields: addressFields,
    append: appendAddress,
    remove: removeAddress,
  } = useFieldArray({ control, name: "addresses" })

  useEffect(() => {
    if (mode !== "create" || !createDraft) return
    reset({
      namePrefix: "",
      firstName: createDraft.firstName ?? "",
      middleName: "",
      lastName: createDraft.lastName ?? "",
      nameSuffix: "",
      phoneticFirstName: "",
      phoneticLastName: "",
      company: "",
      department: "",
      jobTitle: "",
      emails: createDraft.emails?.length
        ? createDraft.emails
        : [{ value: "", label: "Domicile" }],
      phones: [{ value: "", label: "Mobile" }],
      addresses: [],
      birthday: { day: undefined, month: undefined, year: undefined },
      notes: "",
      labels: [],
    })
    clearCreateDraft()
  }, [mode, createDraft, reset, clearCreateDraft])

  useEffect(() => {
    if (existingContact) {
      const hasExtendedName = !!(
        existingContact.namePrefix ||
        existingContact.middleName ||
        existingContact.nameSuffix ||
        existingContact.phoneticFirstName ||
        existingContact.phoneticLastName
      )
      if (hasExtendedName) setNameExpanded(true)
      if (existingContact.department) setCompanyExpanded(true)

      reset({
        namePrefix: existingContact.namePrefix ?? "",
        firstName: existingContact.firstName,
        middleName: existingContact.middleName ?? "",
        lastName: existingContact.lastName,
        nameSuffix: existingContact.nameSuffix ?? "",
        phoneticFirstName: existingContact.phoneticFirstName ?? "",
        phoneticLastName: existingContact.phoneticLastName ?? "",
        company: existingContact.company ?? "",
        department: existingContact.department ?? "",
        jobTitle: existingContact.jobTitle ?? "",
        emails: existingContact.emails.length
          ? existingContact.emails
          : [{ value: "", label: "Domicile" }],
        phones: existingContact.phones.length
          ? existingContact.phones
          : [{ value: "", label: "Mobile" }],
        addresses: existingContact.addresses ?? [],
        birthday: existingContact.birthday ?? {
          day: undefined,
          month: undefined,
          year: undefined,
        },
        notes: existingContact.notes ?? "",
        labels: existingContact.labels ?? [],
      })
    }
  }, [existingContact, reset])

  const firstName = watch("firstName")
  const lastName = watch("lastName")
  const watchedEmails = watch("emails")
  const currentLabels = watch("labels") ?? []
  const displayName = `${firstName ?? ""} ${lastName ?? ""}`.trim()

  const canSave =
    isDirty ||
    (mode === "create" &&
      !!(
        firstName?.trim() ||
        lastName?.trim() ||
        watchedEmails?.some((e) => e.value?.trim())
      ))

  const toggleLabel = useCallback(
    (labelId: string) => {
      const next = currentLabels.includes(labelId)
        ? currentLabels.filter((l) => l !== labelId)
        : [...currentLabels, labelId]
      setValue("labels", next, { shouldDirty: true })
    },
    [currentLabels, setValue],
  )

  function onSubmit(data: ContactFormValues) {
    const payload = {
      namePrefix: data.namePrefix || undefined,
      firstName: data.firstName ?? "",
      middleName: data.middleName || undefined,
      lastName: data.lastName ?? "",
      nameSuffix: data.nameSuffix || undefined,
      phoneticFirstName: data.phoneticFirstName || undefined,
      phoneticLastName: data.phoneticLastName || undefined,
      company: data.company || undefined,
      department: data.department || undefined,
      jobTitle: data.jobTitle || undefined,
      emails: data.emails.filter((e) => e.value),
      phones: data.phones.filter((p) => p.value),
      addresses: data.addresses.filter(
        (a) => a.street || a.city || a.region || a.postalCode || a.country,
      ),
      birthday:
        data.birthday?.day || data.birthday?.month || data.birthday?.year
          ? data.birthday
          : undefined,
      notes: data.notes || undefined,
      labels: data.labels?.length ? data.labels : undefined,
    }

    if (mode === "create") {
      const tempId = crypto.randomUUID()
      const fullContact: FullContact = {
        id: tempId,
        ...payload,
        firstName: payload.firstName ?? "",
        lastName: payload.lastName ?? "",
        emails: payload.emails ?? [],
        phones: payload.phones ?? [],
        createdAt: Date.now(),
        updatedAt: Date.now(),
      }
      createContactMutation.mutate(
        { bookId, contact: fullContactToApiContact(fullContact) },
        {
          onSuccess: (created) => {
            const id = created?.uid ?? tempId
            setView("view", id)
          },
        },
      )
    } else if (contactId) {
      const fullContact: FullContact = {
        id: contactId,
        ...payload,
        firstName: payload.firstName ?? "",
        lastName: payload.lastName ?? "",
        emails: payload.emails ?? [],
        phones: payload.phones ?? [],
        createdAt: Date.now(),
        updatedAt: Date.now(),
      }
      updateContactMutation.mutate({
        path: contactId,
        contact: fullContactToApiContact(fullContact),
      })
      setView("view", contactId)
    }
  }

  const availableLabels = labelRows.filter((r) => r.enabled !== false)

  return (
    <form
      onSubmit={handleSubmit(onSubmit)}
      className={cn("flex h-full flex-col", CONTACTS_PANEL_SHELL_CLASS)}
    >
      <div className={CONTACTS_PANEL_HEADER_CLASS}>
        <ContactsPanelLogo onClick={showContactsList} className="-ml-1" />

        <div className="flex items-center gap-1">
          <Button
            type="button"
            variant="ghost"
            size="icon"
            className="h-8 w-8 rounded-full"
            onClick={() => setStarred((s) => !s)}
          >
            <Star
              className={cn("h-4 w-4", starred ? "fill-yellow-400 text-yellow-400" : CONTACTS_PANEL_MUTED_ICON_CLASS)}
            />
          </Button>

          <button
            type="submit"
            disabled={!canSave}
            className={CONTACTS_PANEL_SAVE_BTN_CLASS}
          >
            Enregistrer
          </button>

          <Button
            type="button"
            variant="ghost"
            size="icon"
            className={CONTACTS_PANEL_ICON_BTN_CLASS}
            onClick={closePanel}
          >
            <X className="h-4 w-4" />
          </Button>
        </div>
      </div>

      <div className="min-h-0 flex-1 overflow-y-auto">
        {/* Avatar */}
        <div className="flex flex-col items-center py-6">
          {displayName ? (
            <div
              className="flex h-20 w-20 items-center justify-center rounded-full text-2xl font-medium text-white"
              style={{ backgroundColor: avatarColor(displayName) }}
            >
              {senderInitial(displayName)}
            </div>
          ) : (
            <div className={CONTACTS_PANEL_AVATAR_PLACEHOLDER_CLASS}>
              <User className="h-8 w-8" />
            </div>
          )}
        </div>

        {/* Labels */}
        <div className="flex flex-wrap items-center justify-center gap-1.5 px-4 pb-4">
          {currentLabels.map((labelId) => {
            const row = labelRows.find((r) => r.id === labelId)
            return (
              <span
                key={labelId}
                className={CONTACTS_PANEL_TAG_CLASS}
              >
                {row && (
                  <span className={`inline-block h-2 w-2 rounded-full ${row.color}`} />
                )}
                {row?.label ?? labelId}
                <button
                  type="button"
                  onClick={() => toggleLabel(labelId)}
                  className="text-muted-foreground hover:text-foreground"
                >
                  <X className="h-3 w-3" />
                </button>
              </span>
            )
          })}
          <Popover>
            <PopoverTrigger asChild>
              <button
                type="button"
                className={CONTACTS_PANEL_ADD_TAG_BTN_CLASS}
              >
                <Plus className="h-3 w-3" />
                Libellé
              </button>
            </PopoverTrigger>
            <PopoverContent className="w-52 p-1" align="center">
              <p className={cn("px-2 py-1.5 text-xs font-medium", CONTACTS_MUTED_TEXT)}>
                Libellés
              </p>
              <div className="max-h-48 overflow-y-auto">
                {availableLabels.map((row) => {
                  const active = currentLabels.includes(row.id)
                  return (
                    <button
                      key={row.id}
                      type="button"
                      onClick={() => toggleLabel(row.id)}
                      className={CONTACTS_PANEL_POPOVER_ITEM_CLASS}
                    >
                      <span className={`h-2.5 w-2.5 shrink-0 rounded-full ${row.color}`} />
                      <span className="flex-1 truncate">{row.label}</span>
                      {active && <Check className="h-3.5 w-3.5 text-blue-600" />}
                    </button>
                  )
                })}
              </div>
            </PopoverContent>
          </Popover>
        </div>

        {/* Name section */}
        <FormSection icon={<User className={cn("h-5 w-5", CONTACTS_PANEL_MUTED_ICON_CLASS)} />}>
          {nameExpanded && (
            <FloatingInput label="Titre (M., Mme...)" {...register("namePrefix")} />
          )}
          <div className="flex items-center gap-1">
            <div className="flex-1">
              <FloatingInput label="Prénom" {...register("firstName")} />
            </div>
            <Button
              type="button"
              variant="ghost"
              size="icon"
              className={cn("h-8 w-8 shrink-0 rounded-full", CONTACTS_PANEL_ICON_BTN_CLASS)}
              onClick={() => setNameExpanded((e) => !e)}
            >
              {nameExpanded ? (
                <ChevronUp className="h-4 w-4" />
              ) : (
                <ChevronDown className="h-4 w-4" />
              )}
            </Button>
          </div>
          {nameExpanded && (
            <FloatingInput label="Deuxième prénom" {...register("middleName")} />
          )}
          <FloatingInput label="Nom" {...register("lastName")} />
          {nameExpanded && (
            <>
              <FloatingInput label="Suffixe (Jr., Sr...)" {...register("nameSuffix")} />
              <FloatingInput label="Prénom phonétique" {...register("phoneticFirstName")} />
              <FloatingInput label="Nom phonétique" {...register("phoneticLastName")} />
            </>
          )}
        </FormSection>

        {/* Company section */}
        <FormSection icon={<Building2 className={cn("h-5 w-5", CONTACTS_PANEL_MUTED_ICON_CLASS)} />}>
          <div className="flex items-center gap-1">
            <div className="flex-1">
              <FloatingInput label="Entreprise" {...register("company")} />
            </div>
            <Button
              type="button"
              variant="ghost"
              size="icon"
              className={cn("h-8 w-8 shrink-0 rounded-full", CONTACTS_PANEL_ICON_BTN_CLASS)}
              onClick={() => setCompanyExpanded((e) => !e)}
            >
              {companyExpanded ? (
                <ChevronUp className="h-4 w-4" />
              ) : (
                <ChevronDown className="h-4 w-4" />
              )}
            </Button>
          </div>
          {companyExpanded && (
            <FloatingInput label="Service" {...register("department")} />
          )}
          <FloatingInput label="Fonction" {...register("jobTitle")} />
        </FormSection>

        {/* Email section */}
        <FormSection icon={<Mail className={cn("h-5 w-5", CONTACTS_PANEL_MUTED_ICON_CLASS)} />}>
          {emailFields.map((field, index) => (
            <div key={field.id} className="space-y-2">
              <div className="flex items-center gap-1">
                <div className="flex-1">
                  <FloatingInput
                    label="E-mail"
                    type="email"
                    {...register(`emails.${index}.value`)}
                  />
                </div>
                {emailFields.length > 1 && (
                  <Button
                    type="button"
                    variant="ghost"
                    size="icon"
                    className={cn("h-8 w-8 shrink-0 rounded-full", CONTACTS_PANEL_ICON_BTN_CLASS)}
                    onClick={() => removeEmail(index)}
                  >
                    <X className="h-3.5 w-3.5" />
                  </Button>
                )}
              </div>
              <Controller
                control={control}
                name={`emails.${index}.label`}
                render={({ field: f }) => (
                  <CompactSelect
                    value={f.value}
                    onValueChange={f.onChange}
                    options={EMAIL_LABELS.map((l) => ({ value: l, label: l }))}
                  />
                )}
              />
            </div>
          ))}
          <AddButton onClick={() => appendEmail({ value: "", label: "Domicile" })}>
            Ajouter une adresse e-mail
          </AddButton>
        </FormSection>

        {/* Phone section */}
        <FormSection icon={<Phone className={cn("h-5 w-5", CONTACTS_PANEL_MUTED_ICON_CLASS)} />}>
          {phoneFields.map((field, index) => (
            <div key={field.id} className="space-y-2">
              <div className="flex items-center gap-2">
                <span className="flex h-8 w-8 shrink-0 items-center justify-center rounded text-sm">
                  🇫🇷
                </span>
                <div className="flex-1">
                  <FloatingInput
                    label="Téléphone"
                    type="tel"
                    {...register(`phones.${index}.value`)}
                  />
                </div>
                {phoneFields.length > 1 && (
                  <Button
                    type="button"
                    variant="ghost"
                    size="icon"
                    className={cn("h-8 w-8 shrink-0 rounded-full", CONTACTS_PANEL_ICON_BTN_CLASS)}
                    onClick={() => removePhone(index)}
                  >
                    <X className="h-3.5 w-3.5" />
                  </Button>
                )}
              </div>
              <Controller
                control={control}
                name={`phones.${index}.label`}
                render={({ field: f }) => (
                  <CompactSelect
                    value={f.value}
                    onValueChange={f.onChange}
                    options={PHONE_LABELS.map((l) => ({ value: l, label: l }))}
                  />
                )}
              />
            </div>
          ))}
          <AddButton onClick={() => appendPhone({ value: "", label: "Mobile" })}>
            Ajouter un numéro de téléphone
          </AddButton>
        </FormSection>

        {/* Address section */}
        <FormSection icon={<MapPin className={cn("h-5 w-5", CONTACTS_PANEL_MUTED_ICON_CLASS)} />}>
          {addressFields.map((field, index) => (
            <div key={field.id} className={CONTACTS_PANEL_CARD_CLASS}>
              <div className="flex items-center justify-between">
                <Controller
                  control={control}
                  name={`addresses.${index}.label`}
                  render={({ field: f }) => (
                    <CompactSelect
                      value={f.value}
                      onValueChange={f.onChange}
                      options={ADDRESS_LABELS.map((l) => ({ value: l, label: l }))}
                    />
                  )}
                />
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  className={cn("h-7 w-7 shrink-0 rounded-full", CONTACTS_PANEL_ICON_BTN_CLASS)}
                  onClick={() => removeAddress(index)}
                >
                  <X className="h-3.5 w-3.5" />
                </Button>
              </div>
              <FloatingInput label="Rue" {...register(`addresses.${index}.street`)} />
              <div className="flex gap-2">
                <div className="w-24">
                  <FloatingInput label="Code postal" {...register(`addresses.${index}.postalCode`)} />
                </div>
                <div className="flex-1">
                  <FloatingInput label="Ville" {...register(`addresses.${index}.city`)} />
                </div>
              </div>
              <FloatingInput label="Région / Province" {...register(`addresses.${index}.region`)} />
              <FloatingInput label="Pays" {...register(`addresses.${index}.country`)} />
            </div>
          ))}
          <AddButton
            onClick={() =>
              appendAddress({
                street: "",
                city: "",
                region: "",
                postalCode: "",
                country: "",
                label: "Domicile",
              })
            }
          >
            Ajouter une adresse
          </AddButton>
        </FormSection>

        {/* Birthday section */}
        <FormSection icon={<Cake className={cn("h-5 w-5", CONTACTS_PANEL_MUTED_ICON_CLASS)} />}>
          <div className="flex items-stretch gap-2">
            <div className="w-[72px]">
              <FloatingInput
                label="Jour"
                type="number"
                min={1}
                max={31}
                {...register("birthday.day", { valueAsNumber: true })}
              />
            </div>
            <div className="flex-1">
              <Controller
                control={control}
                name="birthday.month"
                render={({ field: f }) => (
                  <CompactSelect
                    value={f.value ? String(f.value) : ""}
                    onValueChange={(v) => f.onChange(v ? Number(v) : undefined)}
                    options={FRENCH_MONTHS.map((name, i) => ({
                      value: String(i + 1),
                      label: name,
                    }))}
                    placeholder="Mois"
                  />
                )}
              />
            </div>
            <div className="w-24">
              <FloatingInput
                label="Année"
                type="number"
                min={1900}
                max={2100}
                {...register("birthday.year", { valueAsNumber: true })}
              />
            </div>
          </div>
        </FormSection>

        {/* Notes section */}
        <FormSection icon={<FileText className={cn("h-5 w-5", CONTACTS_PANEL_MUTED_ICON_CLASS)} />}>
          <FloatingTextarea label="Notes" {...register("notes")} />
        </FormSection>

        <div className="h-8" />
      </div>
    </form>
  )
}

/* ─── Layout helpers ─────────────────────────────────────────── */

function FormSection({
  icon,
  children,
}: {
  icon: React.ReactNode
  children: React.ReactNode
}) {
  return (
    <div className="flex gap-3 px-4 py-2">
      <div className="flex w-5 shrink-0 pt-2">{icon}</div>
      <div className="flex-1 space-y-2">{children}</div>
    </div>
  )
}

function AddButton({
  onClick,
  children,
}: {
  onClick: () => void
  children: React.ReactNode
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      className={cn("flex items-center gap-2 py-1", CONTACTS_PANEL_LINK_TEXT_CLASS, "hover:text-primary/80")}
    >
      <Plus className="h-4 w-4" />
      {children}
    </button>
  )
}

/* ─── Floating label input (Material outlined style) ─────── */

interface FloatingInputProps extends InputHTMLAttributes<HTMLInputElement> {
  label: string
}

const FloatingInput = forwardRef<HTMLInputElement, FloatingInputProps>(
  function FloatingInput({ label, className, defaultValue, ...props }, ref) {
    const id = useId()
    const [focused, setFocused] = useState(false)
    const [filled, setFilled] = useState(() => !!defaultValue)
    const innerRef = useRef<HTMLInputElement | null>(null)

    useEffect(() => {
      if (innerRef.current && innerRef.current.value) setFilled(true)
    })

    const setRefs = useCallback(
      (node: HTMLInputElement | null) => {
        innerRef.current = node
        if (typeof ref === "function") ref(node)
        else if (ref) ref.current = node
        if (node && node.value) setFilled(true)
      },
      [ref],
    )

    const floated = focused || filled

    return (
      <div className="relative">
        <input
          ref={setRefs}
          id={id}
          {...props}
          defaultValue={defaultValue}
          className={cn(CONTACTS_PANEL_FLOATING_INPUT_CLASS, className)}
          onFocus={(e) => {
            setFocused(true)
            props.onFocus?.(e)
          }}
          onBlur={(e) => {
            setFocused(false)
            setFilled(!!e.target.value)
            props.onBlur?.(e)
          }}
          onChange={(e) => {
            setFilled(!!e.target.value)
            props.onChange?.(e)
          }}
        />
        <label
          htmlFor={id}
          className={cn(
            CONTACTS_PANEL_FLOATING_LABEL_CLASS,
            floated ? "top-0.5 px-0.5 text-[10px] leading-tight" : "top-[11px] text-sm",
            focused ? "text-primary" : "text-muted-foreground",
          )}
        >
          {label}
        </label>
      </div>
    )
  },
)

/* ─── Floating label textarea ────────────────────────────── */

interface FloatingTextareaProps
  extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
  label: string
}

const FloatingTextarea = forwardRef<HTMLTextAreaElement, FloatingTextareaProps>(
  function FloatingTextarea({ label, className, ...props }, ref) {
    const id = useId()
    const [focused, setFocused] = useState(false)
    const [filled, setFilled] = useState(false)
    const innerRef = useRef<HTMLTextAreaElement | null>(null)

    useEffect(() => {
      if (innerRef.current && innerRef.current.value) setFilled(true)
    })

    const setRefs = useCallback(
      (node: HTMLTextAreaElement | null) => {
        innerRef.current = node
        if (typeof ref === "function") ref(node)
        else if (ref) ref.current = node
        if (node && node.value) setFilled(true)
      },
      [ref],
    )

    const floated = focused || filled

    return (
      <div className="relative">
        <textarea
          ref={setRefs}
          id={id}
          rows={3}
          {...props}
          className={cn(CONTACTS_PANEL_FLOATING_TEXTAREA_CLASS, className)}
          onFocus={(e) => {
            setFocused(true)
            props.onFocus?.(e)
          }}
          onBlur={(e) => {
            setFocused(false)
            setFilled(!!e.target.value)
            props.onBlur?.(e)
          }}
          onChange={(e) => {
            setFilled(!!e.target.value)
            props.onChange?.(e)
          }}
        />
        <label
          htmlFor={id}
          className={cn(
            CONTACTS_PANEL_FLOATING_LABEL_CLASS,
            floated ? "top-1 px-0.5 text-[10px] leading-tight" : "top-2.5 text-sm",
            focused ? "text-primary" : "text-muted-foreground",
          )}
        >
          {label}
        </label>
      </div>
    )
  },
)

/* ─── Compact select (no floating label, just small) ─────── */

function CompactSelect({
  value,
  onValueChange,
  options,
  placeholder,
}: {
  value: string
  onValueChange: (v: string) => void
  options: { value: string; label: string }[]
  placeholder?: string
}) {
  return (
    <Select value={value} onValueChange={onValueChange}>
      <SelectTrigger className={CONTACTS_PANEL_SELECT_TRIGGER_CLASS}>
        <SelectValue placeholder={placeholder ?? "Choisir..."} />
      </SelectTrigger>
      <SelectContent>
        {options.map((opt) => (
          <SelectItem key={opt.value} value={opt.value}>
            {opt.label}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  )
}
