'use client';

import React, { useEffect, useRef, useState } from 'react';
import { useField, useFormikContext } from 'formik';
import { useTranslation } from 'react-i18next';
import { Search, Link2 } from 'lucide-react';
import { FieldGroup } from './FieldGroup';
import { FleetVehicle } from '@/models/teltoinstall/_index';
import { ReferenceRepository } from '@/repositories/teltoinstall/_index';

interface Props {
  name: string;
  label?: string;
  required?: boolean;
  hint?: string;
  /** Verrouillé (pose issue d'une demande) : lecture seule, sans recherche parc. */
  locked?: boolean;
}

/**
 * Champ immatriculation alimenté par le parc fleet : la saisie déclenche une
 * recherche (plaque ou VIN) côté fleet ; sélectionner un véhicule remplit la
 * plaque, le VIN et `fleet_vehicle_id`. La saisie libre reste possible
 * (véhicule absent du parc, ou fleet injoignable) : dans ce cas
 * `fleet_vehicle_id` est remis à null.
 */
export function FleetVehicleField({ name, label, required, hint, locked }: Props) {
  const { t } = useTranslation();
  const [field, meta, helpers] = useField<string>(name);
  const { values, setFieldValue } = useFormikContext<{ fleet_vehicle_id?: number | null }>();
  const showError = meta.touched && Boolean(meta.error);

  const [suggestions, setSuggestions] = useState<FleetVehicle[]>([]);
  const [open, setOpen] = useState(false);
  const [loading, setLoading] = useState(false);
  // L'état « lié au parc » est porté par le formulaire (fleet_vehicle_id),
  // ce qui couvre aussi la reprise d'une installation déjà liée.
  const linked = Boolean(values.fleet_vehicle_id);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);

  // Fermeture du menu au clic extérieur.
  useEffect(() => {
    function onClickOutside(e: MouseEvent) {
      if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
        setOpen(false);
      }
    }
    document.addEventListener('mousedown', onClickOutside);
    return () => document.removeEventListener('mousedown', onClickOutside);
  }, []);

  useEffect(() => () => {
    if (debounceRef.current) clearTimeout(debounceRef.current);
  }, []);

  function search(query: string) {
    if (debounceRef.current) clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(async () => {
      setLoading(true);
      try {
        const vehicles = await ReferenceRepository.fleetVehicles(query);
        setSuggestions(vehicles);
        setOpen(vehicles.length > 0);
      } catch {
        // Fleet injoignable : on laisse la saisie manuelle suivre son cours.
        setSuggestions([]);
        setOpen(false);
      } finally {
        setLoading(false);
      }
    }, 300);
  }

  function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
    const value = e.target.value.toUpperCase();
    helpers.setValue(value);
    // Toute modification manuelle invalide le lien vers le véhicule fleet.
    setFieldValue('fleet_vehicle_id', null);
    if (value.trim().length >= 2) {
      search(value.trim());
    } else {
      setSuggestions([]);
      setOpen(false);
    }
  }

  function selectVehicle(vehicle: FleetVehicle) {
    helpers.setValue(vehicle.license_plate ?? '');
    setFieldValue('fleet_vehicle_id', vehicle.id);
    if (vehicle.vin) setFieldValue('vin', vehicle.vin.toUpperCase());
    setOpen(false);
  }

  // Verrouillé : la plaque vient d'une demande confirmée — lecture seule, pas de
  // recherche parc ni de modification possible.
  if (locked) {
    return (
      <FieldGroup label={label} required={required} hint={hint}>
        <div className="relative">
          <span className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground">
            <Link2 className="w-4 h-4 text-green-600" />
          </span>
          <input
            id={name}
            type="text"
            disabled
            value={field.value ?? ''}
            className="field-input pl-10 uppercase opacity-60 cursor-not-allowed bg-muted"
          />
        </div>
      </FieldGroup>
    );
  }

  return (
    <FieldGroup label={label} required={required} hint={hint} error={showError ? meta.error : undefined}>
      <div className="relative" ref={containerRef}>
        <span className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground">
          {linked ? <Link2 className="w-4 h-4 text-green-600" /> : <Search className="w-4 h-4" />}
        </span>
        <input
          {...field}
          id={name}
          type="text"
          placeholder="Ex: AB-123-CD"
          autoComplete="off"
          value={field.value ?? ''}
          onChange={handleChange}
          onFocus={() => suggestions.length > 0 && setOpen(true)}
          className={`field-input pl-10 uppercase ${
            showError ? 'border-red-400 focus:ring-red-200 focus:border-red-400' : ''
          }`}
        />
        {open && (
          <ul className="absolute z-20 mt-1 w-full max-h-60 overflow-auto rounded-lg border border-gray-200 bg-white shadow-lg">
            {suggestions.map((v) => (
              <li key={v.id}>
                <button
                  type="button"
                  onClick={() => selectVehicle(v)}
                  className="w-full px-3 py-2 text-left hover:bg-gray-50 flex flex-col"
                >
                  <span className="font-medium uppercase">{v.license_plate}</span>
                  <span className="text-xs text-muted-foreground">
                    {[v.make, v.model].filter(Boolean).join(' ')}
                    {v.vin ? ` · ${v.vin}` : ''}
                  </span>
                </button>
              </li>
            ))}
          </ul>
        )}
      </div>
      {loading ? (
        <p className="text-xs text-muted-foreground">{t('vehicle.fleetSearching')}</p>
      ) : linked ? (
        <p className="text-xs text-green-600">{t('vehicle.fleetLinked')}</p>
      ) : (field.value ?? '').trim().length >= 2 ? (
        // Plaque saisie mais introuvable dans le parc : on explique la
        // conséquence (installation finalisée en « En attente »).
        <p className="text-xs text-amber-600">{t('vehicle.fleetNotLinked')}</p>
      ) : (
        <p className="text-xs text-muted-foreground">{t('vehicle.fleetSearchHelper')}</p>
      )}
    </FieldGroup>
  );
}
