"use client";

import { useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import type { AxiosError } from "axios";
import {
  ArrowLeft,
  Car,
  Cpu,
  Cable,
  ClipboardCheck,
  Check,
  Loader2,
  AlertTriangle,
  Plus,
  Trash2,
  Search,
  Link2,
  Link2Off,
  Save,
  CheckCircle2,
} from "lucide-react";
import { useRepositories } from "@/di/repository-provider";
import { useApiQuery } from "@/presentation/hooks/use-api-query";
import { useT } from "@/shared/i18n/client";
import { usePageHeader } from "@/presentation/hooks/use-page-header";
import { ROUTES } from "@/shared/constants";
import { Button } from "@/presentation/components/ui/button";
import { Input } from "@/presentation/components/ui/input";
import { Label } from "@/presentation/components/ui/label";
import { Textarea } from "@/presentation/components/ui/textarea";
import { Checkbox } from "@/presentation/components/ui/checkbox";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/presentation/components/ui/select";
import type {
  InstallationDetail,
  InstallationEditOptions,
  UpdateInstallationPayload,
} from "@/domain/entities/installation";
import type { Vehicle } from "@/domain/entities/vehicle";

const FUEL_LEVELS = ["none", "quarter", "half", "three_quarters", "full"];
const STEPS = ["vehicle", "device", "wiring", "summary"] as const;
const STEP_ICONS = [Car, Cpu, Cable, ClipboardCheck];

interface FormState {
  installer_name: string;
  intervention_date: string;
  location: string;
  notes: string;
  license_plate: string;
  vin: string;
  fleet_vehicle_id: number | null;
  odometer_km: string;
  hour_meter: string;
  fuel_level: string;
  telematics_box_id: string;
  stock_origin: string;
  imei: string;
  has_can_module: boolean;
  can_module_type_id: string;
  sim_iccid: string;
}

type WiringRow = { wire_id: string; wire_accessory_id: string };

/** Extrait les messages d'une réponse 422 (validation ou complétude). */
function extractErrors(err: unknown): string[] {
  const axiosError = err as AxiosError<{
    message?: string;
    errors?: string[] | Record<string, string[]>;
  }>;
  const data = axiosError.response?.data;
  if (!data) return [];
  if (Array.isArray(data.errors)) return data.errors;
  if (data.errors && typeof data.errors === "object") {
    return Object.values(data.errors).flat();
  }
  return data.message ? [data.message] : [];
}

function buildInitialForm(installation: InstallationDetail): FormState {
  return {
    installer_name: installation.installer_name ?? "",
    intervention_date: installation.intervention_date ?? "",
    location: installation.location ?? "",
    notes: installation.notes ?? "",
    license_plate: installation.vehicle?.license_plate ?? "",
    vin: installation.vehicle?.vin ?? "",
    fleet_vehicle_id: installation.vehicle?.fleet_vehicle_id ?? null,
    odometer_km: installation.vehicle?.odometer_km?.toString() ?? "",
    hour_meter: installation.vehicle?.hour_meter?.toString() ?? "",
    fuel_level: installation.vehicle?.fuel_level ?? "",
    telematics_box_id: installation.device?.telematics_box_id?.toString() ?? "",
    stock_origin: installation.device?.stock_origin ?? "",
    imei: installation.device?.imei ?? "",
    has_can_module: installation.device?.has_can_module ?? false,
    can_module_type_id: installation.device?.can_module_type_id?.toString() ?? "",
    sim_iccid: installation.device?.sim_iccid ?? "",
  };
}

function buildPayload(
  form: FormState,
  accessoryIds: number[],
  wirings: WiringRow[],
  options: InstallationEditOptions | null,
  installation: InstallationDetail
): UpdateInstallationPayload {
  const payload: UpdateInstallationPayload = {
    installer_name: form.installer_name || null,
    intervention_date: form.intervention_date || null,
    location: form.location || null,
    notes: form.notes || null,
    accessories: accessoryIds,
    wirings: wirings
      .filter((row) => row.wire_id !== "")
      .map((row) => ({
        wire_id: Number(row.wire_id),
        wire_accessory_id: row.wire_accessory_id ? Number(row.wire_accessory_id) : null,
      })),
  };

  if (form.license_plate.trim()) {
    payload.vehicle = {
      license_plate: form.license_plate.trim().toUpperCase(),
      vin: form.vin.trim() ? form.vin.trim().toUpperCase() : null,
      fleet_vehicle_id: form.fleet_vehicle_id,
      odometer_km: form.odometer_km !== "" ? Number(form.odometer_km) : null,
      hour_meter: form.hour_meter !== "" ? Number(form.hour_meter) : null,
      fuel_level: form.fuel_level || null,
    };
  }

  if (form.telematics_box_id && form.stock_origin && form.imei.trim()) {
    // Gamme/modèle : snapshots dérivés du produit du catalogue choisi.
    const box = options?.telematics_boxes.find(
      (b) => String(b.id) === form.telematics_box_id
    );
    payload.device = {
      telematics_box_id: Number(form.telematics_box_id),
      stock_origin: form.stock_origin,
      imei: form.imei.trim(),
      product_line: box?.product_line ?? installation.device?.product_line,
      model: box?.model ?? installation.device?.model,
      has_can_module: form.has_can_module,
      can_module_type_id:
        form.has_can_module && form.can_module_type_id
          ? Number(form.can_module_type_id)
          : null,
      sim_card: { iccid: form.sim_iccid || null },
    };
  }

  return payload;
}

/** Recherche d'un véhicule du parc fleet (rattachement / re-rattachement). */
function FleetVehiclePicker({
  fleetVehicleId,
  onSelect,
  onUnlink,
}: {
  fleetVehicleId: number | null;
  onSelect: (vehicle: Vehicle) => void;
  onUnlink: () => void;
}) {
  const t = useT();
  const d = t.installations.detail;
  const container = useRepositories();
  const [query, setQuery] = useState("");
  const [suggestions, setSuggestions] = useState<Vehicle[]>([]);
  const [open, setOpen] = useState(false);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

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

  function handleQuery(value: string) {
    setQuery(value);
    if (debounceRef.current) clearTimeout(debounceRef.current);
    if (value.trim().length < 2) {
      setSuggestions([]);
      setOpen(false);
      return;
    }
    debounceRef.current = setTimeout(async () => {
      try {
        const res = await container.vehicleRepository.findAll({
          page: 1,
          per_page: 8,
          search: value.trim(),
        });
        setSuggestions(res.items ?? []);
        setOpen(true);
      } catch {
        setSuggestions([]);
        setOpen(false);
      }
    }, 300);
  }

  return (
    <div className="space-y-1.5">
      <div className="flex items-center justify-between">
        <Label>{d.fields.fleetVehicle}</Label>
        {fleetVehicleId ? (
          <span className="inline-flex items-center gap-1.5 text-xs text-emerald-700">
            <Link2 className="w-3 h-3" />
            {d.fields.fleetLinked(fleetVehicleId)}
            <button
              type="button"
              onClick={onUnlink}
              className="ml-1 text-red-500 hover:underline"
            >
              {d.actions.unlinkFleet}
            </button>
          </span>
        ) : (
          <span className="inline-flex items-center gap-1.5 text-xs text-amber-600">
            <Link2Off className="w-3 h-3" />
            {d.fields.fleetNotLinked}
          </span>
        )}
      </div>
      <div className="relative">
        <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-muted-foreground" />
        <Input
          className="pl-9"
          value={query}
          placeholder={d.actions.fleetSearchPlaceholder}
          onChange={(e) => handleQuery(e.target.value)}
          onFocus={() => suggestions.length > 0 && setOpen(true)}
        />
        {open && (
          <ul className="absolute z-30 mt-1 w-full max-h-52 overflow-auto rounded-lg border border-border bg-popover shadow-lg">
            {suggestions.length === 0 ? (
              <li className="px-3 py-2 text-sm text-muted-foreground">
                {d.actions.fleetSearchEmpty}
              </li>
            ) : (
              suggestions.map((vehicle) => (
                <li key={vehicle.id}>
                  <button
                    type="button"
                    className="w-full px-3 py-2 text-left hover:bg-muted flex flex-col"
                    onClick={() => {
                      onSelect(vehicle);
                      setQuery("");
                      setOpen(false);
                    }}
                  >
                    <span className="text-sm font-medium font-mono uppercase">
                      {vehicle.numberplate}
                    </span>
                    <span className="text-xs text-muted-foreground">
                      {[vehicle.mark, vehicle.model].filter(Boolean).join(" ")}
                      {vehicle.vin ? ` · ${vehicle.vin}` : ""}
                    </span>
                  </button>
                </li>
              ))
            )}
          </ul>
        )}
      </div>
    </div>
  );
}

interface StepProps {
  form: FormState;
  update: (patch: Partial<FormState>) => void;
  options: InstallationEditOptions | null;
}

function VehicleStep({ form, update }: StepProps) {
  const t = useT();
  const d = t.installations.detail;
  const set = (key: keyof FormState) => (value: string) => update({ [key]: value });

  return (
    <div className="space-y-4">
      <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
        <div className="space-y-1.5">
          <Label>{d.fields.installer}</Label>
          <Input
            value={form.installer_name}
            onChange={(e) => set("installer_name")(e.target.value)}
          />
        </div>
        <div className="space-y-1.5">
          <Label>{d.fields.interventionDate}</Label>
          <Input
            type="date"
            value={form.intervention_date}
            onChange={(e) => set("intervention_date")(e.target.value)}
          />
        </div>
        <div className="space-y-1.5 sm:col-span-2">
          <Label>{d.fields.location}</Label>
          <Input
            value={form.location}
            onChange={(e) => set("location")(e.target.value)}
          />
        </div>
      </div>

      <div className="border-t border-border pt-4" />

      <FleetVehiclePicker
        fleetVehicleId={form.fleet_vehicle_id}
        onSelect={(vehicle) =>
          update({
            fleet_vehicle_id: vehicle.id,
            license_plate: vehicle.numberplate?.toUpperCase() ?? form.license_plate,
            vin: vehicle.vin?.toUpperCase() ?? form.vin,
          })
        }
        onUnlink={() => update({ fleet_vehicle_id: null })}
      />
      <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
        <div className="space-y-1.5">
          <Label>{d.fields.licensePlate}</Label>
          <Input
            className="font-mono uppercase"
            value={form.license_plate}
            onChange={(e) => set("license_plate")(e.target.value.toUpperCase())}
          />
        </div>
        <div className="space-y-1.5">
          <Label>{d.fields.vin}</Label>
          <Input
            className="font-mono uppercase"
            maxLength={17}
            value={form.vin}
            onChange={(e) => set("vin")(e.target.value.toUpperCase())}
          />
        </div>
        <div className="space-y-1.5">
          <Label>{d.fields.odometer}</Label>
          <Input
            type="number"
            min={0}
            value={form.odometer_km}
            onChange={(e) => set("odometer_km")(e.target.value)}
          />
        </div>
        <div className="space-y-1.5">
          <Label>{d.fields.hourMeter}</Label>
          <Input
            type="number"
            min={0}
            value={form.hour_meter}
            onChange={(e) => set("hour_meter")(e.target.value)}
          />
        </div>
        <div className="space-y-1.5">
          <Label>{d.fields.fuelLevel}</Label>
          <Select
            value={form.fuel_level || "none_set"}
            onValueChange={(v) => set("fuel_level")(v === "none_set" ? "" : v)}
          >
            <SelectTrigger className="w-full">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="none_set">—</SelectItem>
              {FUEL_LEVELS.map((level) => (
                <SelectItem key={level} value={level}>
                  {d.fuelLevels[level] ?? level}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      </div>
    </div>
  );
}

function DeviceStep({ form, update, options }: StepProps) {
  const t = useT();
  const d = t.installations.detail;
  const set = (key: keyof FormState) => (value: string | boolean) =>
    update({ [key]: value });

  return (
    <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
      <div className="space-y-1.5">
        <Label>{d.fields.telematicsBox}</Label>
        <Select
          value={form.telematics_box_id || undefined}
          onValueChange={(v) => set("telematics_box_id")(v)}
        >
          <SelectTrigger className="w-full">
            <SelectValue placeholder="—" />
          </SelectTrigger>
          <SelectContent>
            {(options?.telematics_boxes ?? []).map((box) => (
              <SelectItem key={box.id} value={String(box.id)}>
                {box.name}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>
      <div className="space-y-1.5">
        <Label>{d.fields.stockOrigin}</Label>
        <Select
          value={form.stock_origin || undefined}
          onValueChange={(v) => set("stock_origin")(v)}
        >
          <SelectTrigger className="w-full">
            <SelectValue placeholder="—" />
          </SelectTrigger>
          <SelectContent>
            {Object.entries(d.stockOrigins).map(([value, label]) => (
              <SelectItem key={value} value={value}>
                {label}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
      </div>
      <div className="space-y-1.5">
        <Label>{d.fields.imei}</Label>
        <Input
          className="font-mono"
          maxLength={15}
          value={form.imei}
          onChange={(e) => set("imei")(e.target.value.replace(/\D/g, ""))}
        />
      </div>
      <div className="space-y-1.5">
        <Label>{d.fields.canModule}</Label>
        <div className="flex items-center gap-3 h-9">
          <Checkbox
            checked={form.has_can_module}
            onCheckedChange={(checked) => set("has_can_module")(checked === true)}
          />
          {form.has_can_module && (
            <Select
              value={form.can_module_type_id || undefined}
              onValueChange={(v) => set("can_module_type_id")(v)}
            >
              <SelectTrigger className="flex-1">
                <SelectValue placeholder={d.fields.canModuleType} />
              </SelectTrigger>
              <SelectContent>
                {(options?.can_module_types ?? []).map((type) => (
                  <SelectItem key={type.id} value={String(type.id)}>
                    {type.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          )}
        </div>
      </div>
      <div className="space-y-1.5">
        <Label>{d.fields.simIccid}</Label>
        <Input
          className="font-mono"
          maxLength={22}
          value={form.sim_iccid}
          onChange={(e) => set("sim_iccid")(e.target.value.replace(/\D/g, ""))}
        />
      </div>
    </div>
  );
}

function WiringStep({
  options,
  accessoryIds,
  setAccessoryIds,
  wirings,
  setWirings,
}: {
  options: InstallationEditOptions | null;
  accessoryIds: number[];
  setAccessoryIds: React.Dispatch<React.SetStateAction<number[]>>;
  wirings: WiringRow[];
  setWirings: React.Dispatch<React.SetStateAction<WiringRow[]>>;
}) {
  const t = useT();
  const d = t.installations.detail;

  function toggleAccessory(id: number) {
    setAccessoryIds((ids) =>
      ids.includes(id) ? ids.filter((x) => x !== id) : [...ids, id]
    );
  }

  return (
    <div className="space-y-6">
      <div className="space-y-3">
        <p className="text-sm font-semibold text-foreground">{d.sections.accessories}</p>
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
          {(options?.accessories ?? []).map((accessory) => (
            <label
              key={accessory.id}
              className="flex items-center gap-2 text-sm text-foreground cursor-pointer"
            >
              <Checkbox
                checked={accessoryIds.includes(accessory.id)}
                onCheckedChange={() => toggleAccessory(accessory.id)}
              />
              {accessory.label}
            </label>
          ))}
        </div>
      </div>

      <div className="space-y-3 border-t border-border pt-4">
        <p className="text-sm font-semibold text-foreground">{d.sections.wiring}</p>
        {wirings.map((row, index) => (
          <div key={index} className="flex items-center gap-2">
            <Select
              value={row.wire_id || undefined}
              onValueChange={(v) =>
                setWirings((rows) =>
                  rows.map((r, i) => (i === index ? { ...r, wire_id: v } : r))
                )
              }
            >
              <SelectTrigger className="w-36">
                <SelectValue placeholder={d.fields.wire} />
              </SelectTrigger>
              <SelectContent>
                {(options?.wires ?? []).map((wire) => (
                  <SelectItem key={wire.id} value={String(wire.id)}>
                    {wire.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Select
              value={row.wire_accessory_id || "none_set"}
              onValueChange={(v) =>
                setWirings((rows) =>
                  rows.map((r, i) =>
                    i === index
                      ? { ...r, wire_accessory_id: v === "none_set" ? "" : v }
                      : r
                  )
                )
              }
            >
              <SelectTrigger className="flex-1">
                <SelectValue placeholder={d.fields.accessory} />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="none_set">—</SelectItem>
                {(options?.wire_accessories ?? []).map((accessory) => (
                  <SelectItem key={accessory.id} value={String(accessory.id)}>
                    {accessory.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Button
              variant="ghost"
              size="icon-sm"
              onClick={() => setWirings((rows) => rows.filter((_, i) => i !== index))}
            >
              <Trash2 className="w-4 h-4 text-red-500" />
            </Button>
          </div>
        ))}
        <Button
          variant="outline"
          size="sm"
          onClick={() =>
            setWirings((rows) => [...rows, { wire_id: "", wire_accessory_id: "" }])
          }
        >
          <Plus className="w-4 h-4 mr-1.5" />
          {d.actions.addWiring}
        </Button>
      </div>
    </div>
  );
}

function SummaryRow({ label, value }: { label: string; value?: string | number | null }) {
  return (
    <div className="flex items-center justify-between gap-4 px-4 py-2 text-sm">
      <span className="text-muted-foreground">{label}</span>
      <span className="text-foreground text-right">
        {value !== null && value !== undefined && value !== "" ? value : "—"}
      </span>
    </div>
  );
}

function SummaryStep({
  form,
  update,
  options,
  accessoryIds,
  wirings,
}: {
  form: FormState;
  update: (patch: Partial<FormState>) => void;
  options: InstallationEditOptions | null;
  accessoryIds: number[];
  wirings: WiringRow[];
}) {
  const t = useT();
  const d = t.installations.detail;
  const e = t.installations.edit;
  const box = options?.telematics_boxes.find(
    (b) => String(b.id) === form.telematics_box_id
  );
  const accessoryLabels = (options?.accessories ?? [])
    .filter((a) => accessoryIds.includes(a.id))
    .map((a) => a.label);

  return (
    <div className="space-y-4">
      <p className="text-sm text-muted-foreground">{e.summaryHint}</p>

      <div className="border border-border rounded-xl overflow-hidden">
        <div className="px-4 py-2 bg-muted/50 text-sm font-semibold">
          {d.sections.vehicle}
        </div>
        <div className="divide-y divide-border">
          <SummaryRow label={d.fields.licensePlate} value={form.license_plate} />
          <SummaryRow label={d.fields.vin} value={form.vin} />
          <SummaryRow
            label={d.fields.fleetVehicle}
            value={form.fleet_vehicle_id ? `#${form.fleet_vehicle_id}` : d.fields.fleetNotLinked}
          />
          <SummaryRow
            label={d.fields.odometer}
            value={form.odometer_km ? `${form.odometer_km} km` : null}
          />
          <SummaryRow label={d.fields.hourMeter} value={form.hour_meter} />
          <SummaryRow
            label={d.fields.fuelLevel}
            value={form.fuel_level ? d.fuelLevels[form.fuel_level] ?? form.fuel_level : null}
          />
        </div>
      </div>

      <div className="border border-border rounded-xl overflow-hidden">
        <div className="px-4 py-2 bg-muted/50 text-sm font-semibold">
          {d.sections.device}
        </div>
        <div className="divide-y divide-border">
          <SummaryRow label={d.fields.telematicsBox} value={box?.name} />
          <SummaryRow label={d.fields.model} value={box?.model} />
          <SummaryRow label={d.fields.imei} value={form.imei} />
          <SummaryRow
            label={d.fields.stockOrigin}
            value={form.stock_origin ? d.stockOrigins[form.stock_origin] ?? form.stock_origin : null}
          />
          <SummaryRow label={d.fields.simIccid} value={form.sim_iccid} />
        </div>
      </div>

      <div className="border border-border rounded-xl overflow-hidden">
        <div className="px-4 py-2 bg-muted/50 text-sm font-semibold">
          {d.sections.wiring}
        </div>
        <div className="px-4 py-2.5 flex flex-wrap gap-1.5">
          {accessoryLabels.length === 0 && wirings.length === 0 ? (
            <span className="text-sm text-muted-foreground">—</span>
          ) : (
            <>
              {accessoryLabels.map((label) => (
                <span
                  key={label}
                  className="text-xs px-2 py-1 rounded-full bg-primary/10 text-primary"
                >
                  {label}
                </span>
              ))}
              <span className="text-xs px-2 py-1 rounded-full bg-muted text-muted-foreground">
                {wirings.filter((w) => w.wire_id).length} {d.sections.wiring.toLowerCase()}
              </span>
            </>
          )}
        </div>
      </div>

      <div className="space-y-1.5">
        <Label>{d.sections.notes}</Label>
        <Textarea
          rows={3}
          value={form.notes}
          onChange={(ev) => update({ notes: ev.target.value })}
        />
      </div>
    </div>
  );
}

/**
 * Formulaire wizard proprement dit : monté seulement une fois l'installation
 * chargée, l'état est initialisé directement depuis les props (pas d'effet).
 */
function EditWizardForm({
  installation,
  options,
}: {
  installation: InstallationDetail;
  options: InstallationEditOptions | null;
}) {
  const t = useT();
  const e = t.installations.edit;
  const d = t.installations.detail;
  const router = useRouter();
  const container = useRepositories();

  const [step, setStep] = useState(0);
  const [form, setForm] = useState<FormState>(() => buildInitialForm(installation));
  const [accessoryIds, setAccessoryIds] = useState<number[]>(() =>
    installation.accessories.map((a) => a.id)
  );
  const [wirings, setWirings] = useState<WiringRow[]>(() =>
    installation.wirings
      .filter((w) => w.wire_id !== null)
      .map((w) => ({
        wire_id: String(w.wire_id),
        wire_accessory_id: w.wire_accessory_id?.toString() ?? "",
      }))
  );
  const [saving, setSaving] = useState(false);
  const [errors, setErrors] = useState<string[]>([]);

  const update = (patch: Partial<FormState>) => setForm((f) => ({ ...f, ...patch }));

  async function persist(): Promise<void> {
    const payload = buildPayload(form, accessoryIds, wirings, options, installation);
    await container.installationRepository.update(installation.id, payload);
  }

  async function handleSave() {
    setSaving(true);
    setErrors([]);
    try {
      await persist();
      toast.success(e.savedToast);
      router.push(ROUTES.installations);
    } catch (err) {
      const messages = extractErrors(err);
      setErrors(messages.length > 0 ? messages : [e.saveError]);
      setSaving(false);
    }
  }

  async function handleSaveAndValidate() {
    setSaving(true);
    setErrors([]);
    try {
      await persist();
      await container.installationRepository.validate(installation.id);
      toast.success(d.actions.validate);
      router.push(ROUTES.installations);
    } catch (err) {
      const messages = extractErrors(err);
      setErrors(messages.length > 0 ? messages : [e.saveError]);
      setSaving(false);
    }
  }

  const isLast = step === STEPS.length - 1;

  return (
    <div className="max-w-3xl mx-auto space-y-6">
      <div className="flex items-center gap-3">
        <Button variant="outline" size="icon-sm" onClick={() => router.push(ROUTES.installations)}>
          <ArrowLeft className="w-4 h-4" />
        </Button>
        <div>
          <h1 className="text-lg font-semibold text-foreground">{e.title}</h1>
          <p className="text-xs text-muted-foreground font-mono">
            {installation.vehicle?.license_plate ?? t.installations.card.noPlate}
          </p>
        </div>
      </div>

      {/* Stepper */}
      <div className="flex items-center">
        {STEPS.map((key, index) => {
          const Icon = STEP_ICONS[index];
          const done = index < step;
          const active = index === step;
          return (
            <div key={key} className="flex items-center flex-1 last:flex-none">
              <button
                type="button"
                onClick={() => setStep(index)}
                className="flex items-center gap-2"
              >
                <span
                  className={`flex items-center justify-center w-8 h-8 rounded-full border text-sm shrink-0 ${
                    active
                      ? "bg-primary text-primary-foreground border-primary"
                      : done
                        ? "bg-primary/10 text-primary border-primary/30"
                        : "bg-muted text-muted-foreground border-border"
                  }`}
                >
                  {done ? <Check className="w-4 h-4" /> : <Icon className="w-4 h-4" />}
                </span>
                <span
                  className={`text-xs font-medium hidden sm:block ${
                    active ? "text-foreground" : "text-muted-foreground"
                  }`}
                >
                  {e.steps[key]}
                </span>
              </button>
              {index < STEPS.length - 1 && (
                <span className="flex-1 h-px bg-border mx-2" />
              )}
            </div>
          );
        })}
      </div>

      {errors.length > 0 && (
        <div className="flex items-start gap-2 p-3 bg-red-50 border border-red-200 rounded-lg">
          <AlertTriangle className="w-4 h-4 text-red-600 shrink-0 mt-0.5" />
          <div className="text-sm text-red-600">
            <p className="font-medium">{d.actions.incomplete}</p>
            <ul className="mt-0.5 space-y-0.5 list-disc list-inside">
              {errors.map((message) => (
                <li key={message}>{message}</li>
              ))}
            </ul>
          </div>
        </div>
      )}

      {/* Step body */}
      <div className="bg-card border border-border rounded-xl p-5">
        {step === 0 && <VehicleStep form={form} update={update} options={options} />}
        {step === 1 && <DeviceStep form={form} update={update} options={options} />}
        {step === 2 && (
          <WiringStep
            options={options}
            accessoryIds={accessoryIds}
            setAccessoryIds={setAccessoryIds}
            wirings={wirings}
            setWirings={setWirings}
          />
        )}
        {step === 3 && (
          <SummaryStep
            form={form}
            update={update}
            options={options}
            accessoryIds={accessoryIds}
            wirings={wirings}
          />
        )}
      </div>

      {/* Footer nav */}
      <div className="flex items-center justify-between">
        <Button
          variant="outline"
          onClick={() => setStep((s) => Math.max(0, s - 1))}
          disabled={step === 0 || saving}
        >
          {e.previous}
        </Button>

        {!isLast ? (
          <Button onClick={() => setStep((s) => Math.min(STEPS.length - 1, s + 1))}>
            {e.next}
          </Button>
        ) : (
          <div className="flex items-center gap-2">
            <Button variant="outline" onClick={handleSave} disabled={saving}>
              {saving ? (
                <Loader2 className="w-4 h-4 mr-2 animate-spin" />
              ) : (
                <Save className="w-4 h-4 mr-2" />
              )}
              {e.save}
            </Button>
            <Button onClick={handleSaveAndValidate} disabled={saving}>
              {saving ? (
                <Loader2 className="w-4 h-4 mr-2 animate-spin" />
              ) : (
                <CheckCircle2 className="w-4 h-4 mr-2" />
              )}
              {e.saveAndValidate}
            </Button>
          </div>
        )}
      </div>
    </div>
  );
}

/**
 * Point d'entrée de la page d'édition : charge l'installation et les
 * référentiels, puis monte le formulaire wizard une fois prêt.
 */
export function InstallationEditWizard({ installationId }: { installationId: number }) {
  const t = useT();
  const e = t.installations.edit;
  const d = t.installations.detail;
  const container = useRepositories();
  usePageHeader(e.title, "");

  const { data: installation, loading } = useApiQuery(
    () => container.installationRepository.findById(installationId),
    { deps: [installationId] }
  );

  const { data: options } = useApiQuery(
    () => container.installationRepository.getEditOptions(),
    { deps: [] }
  );

  if (loading) {
    return (
      <div className="flex items-center justify-center py-24">
        <Loader2 className="w-6 h-6 animate-spin text-muted-foreground" />
      </div>
    );
  }

  if (!installation) {
    return (
      <div className="flex items-center gap-2 p-3 bg-red-50 border border-red-200 rounded-lg">
        <AlertTriangle className="w-4 h-4 text-red-600 shrink-0" />
        <p className="text-sm text-red-600">{d.notFound}</p>
      </div>
    );
  }

  return <EditWizardForm installation={installation} options={options} />;
}
