"use client";

import {
  DashboardEmptyState,
  DashboardListRow,
  DashboardPageIntro,
  DashboardSection,
  DashboardToolbar,
} from "@/components/dashboard-page";
import { PaginatedListFooter } from "@/components/paginated-list-footer";
import { usePrompt } from "@/components/prompt-provider";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { ErrorState } from "@/components/ui/error-state";
import { Field } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { SkeletonListRow } from "@/components/ui/skeleton";
import { useToast } from "@/hooks/use-toast";
import { catalogosApi, clientesApi, vehiculosApi } from "@/lib/api";
import { fetchCatalogWithCache } from "@/lib/catalogos-offline";
import { db } from "@/lib/db";
import {
  cacheRemoteVehiculos,
  createVehiculoWithOffline,
  getLocalVehiculos,
} from "@/lib/offline-vehiculos";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Car, Pencil, Plus, Search, Users, X } from "lucide-react";
import { useMemo, useRef, useState } from "react";

const DEFAULT_PAGE_SIZE = 9;
const PAGE_SIZE_OPTIONS = [9, 18, 36, 72];

function uniqByNombre(items: any[]) {
  const map = new Map<string, any>();
  for (const item of items || []) {
    const key = String(item?.nombre || "")
      .trim()
      .toLowerCase();
    if (key && !map.has(key)) {
      map.set(key, item);
    }
  }
  return Array.from(map.values());
}

function toOptionList(values: string[]) {
  return uniqByNombre(
    values
      .filter(Boolean)
      .map((nombre, idx) => ({ id: `local-${idx}-${nombre}`, nombre })),
  );
}

function mergeOptions(primary: any[], secondary: any[]) {
  return uniqByNombre([...(primary || []), ...(secondary || [])]);
}

function withCurrentOption(options: any[], currentValue: string) {
  if (!currentValue?.trim()) return options;
  const exists = options.some(
    (option) =>
      String(option?.nombre || "").toLowerCase() === currentValue.toLowerCase(),
  );
  if (exists) return options;
  return [{ id: `current-${currentValue}`, nombre: currentValue }, ...options];
}

export default function VehiculosPage() {
  const prompt = usePrompt();
  const { toast } = useToast();
  const queryClient = useQueryClient();
  const lastRefreshKey = useRef("");
  const hasShownSyncError = useRef(false);

  const [searchTerm, setSearchTerm] = useState("");
  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(DEFAULT_PAGE_SIZE);
  const [showForm, setShowForm] = useState(false);
  const [editing, setEditing] = useState<any>(null);
  const [formData, setFormData] = useState({
    placa: "",
    marca: "",
    modelo: "",
    anio: "",
    motor: "",
    cilindraje: "",
    color: "",
    tipoVehiculoId: "",
    clienteIds: "",
  });
  const [clienteSearch, setClienteSearch] = useState("");

  const resetForm = () => {
    setShowForm(false);
    setEditing(null);
    setClienteSearch("");
    setFormData({
      placa: "",
      marca: "",
      modelo: "",
      anio: "",
      motor: "",
      cilindraje: "",
      color: "",
      tipoVehiculoId: "",
      clienteIds: "",
    });
  };

  const { data: vehiculosData, isLoading, isError, refetch } = useQuery({
    queryKey: ["vehiculos", "list", searchTerm, page, limit],
    queryFn: async () => {
      const normalizedSearch = searchTerm.trim();
      const refreshKey =
        normalizedSearch.length >= 2
          ? `search:${normalizedSearch.toLowerCase()}`
          : "full";

      if (navigator.onLine && lastRefreshKey.current !== refreshKey) {
        lastRefreshKey.current = refreshKey;

        void (async () => {
          try {
            const remote =
              normalizedSearch.length >= 2
                ? await vehiculosApi.search(normalizedSearch)
                : await vehiculosApi.list();

            if (Array.isArray(remote) && remote.length > 0) {
              await cacheRemoteVehiculos(remote);
            }

            hasShownSyncError.current = false;
            await queryClient.invalidateQueries({
              queryKey: ["vehiculos", "list"],
            });
          } catch (error) {
            console.warn("Using local vehicle cache", error);
            if (!hasShownSyncError.current) {
              hasShownSyncError.current = true;
              toast({
                variant: "destructive",
                title: "No se pudo actualizar",
                description: "Mostrando vehículos guardados en este dispositivo. Revisa la conexión con el servidor.",
              });
            }
          }
        })();
      }

      return getLocalVehiculos({ search: normalizedSearch, page, limit });
    },
  });

  const { data: vehiculosSourceData } = useQuery({
    queryKey: ["vehiculos", "form-source"],
    queryFn: () => getLocalVehiculos({ page: 1, limit: 1000 }),
  });

  const { data: tiposVehiculo } = useQuery({
    queryKey: ["catalogos", "tipos-vehiculo"],
    queryFn: () =>
      fetchCatalogWithCache("tipo_vehiculo", catalogosApi.tiposVehiculo),
  });
  const selectedTipoVehiculoId = formData.tipoVehiculoId
    ? Number(formData.tipoVehiculoId)
    : undefined;

  const { data: marcas = [] } = useQuery({
    queryKey: ["catalogos", "vehicular", "marca", selectedTipoVehiculoId],
    queryFn: () =>
      catalogosApi.vehicular(
        "marca",
        selectedTipoVehiculoId
          ? { tipoVehiculoId: selectedTipoVehiculoId }
          : {},
      ),
    enabled: Boolean(selectedTipoVehiculoId),
  });
  const { data: modelos = [] } = useQuery({
    queryKey: [
      "catalogos",
      "vehicular",
      "modelo",
      selectedTipoVehiculoId,
      formData.marca,
    ],
    queryFn: () =>
      catalogosApi.vehicular(
        "modelo",
        formData.marca && selectedTipoVehiculoId
          ? { marca: formData.marca, tipoVehiculoId: selectedTipoVehiculoId }
          : {},
      ),
    enabled: Boolean(formData.marca && selectedTipoVehiculoId),
  });
  const { data: motores = [] } = useQuery({
    queryKey: [
      "catalogos",
      "vehicular",
      "motor",
      selectedTipoVehiculoId,
      formData.marca,
      formData.modelo,
    ],
    queryFn: () =>
      catalogosApi.vehicular(
        "motor",
        formData.marca && formData.modelo && selectedTipoVehiculoId
          ? {
              marca: formData.marca,
              modelo: formData.modelo,
              tipoVehiculoId: selectedTipoVehiculoId,
            }
          : {},
      ),
    enabled: Boolean(
      formData.marca && formData.modelo && selectedTipoVehiculoId,
    ),
  });
  const { data: cilindrajes = [] } = useQuery({
    queryKey: [
      "catalogos",
      "vehicular",
      "cilindraje",
      selectedTipoVehiculoId,
      formData.marca,
      formData.modelo,
      formData.motor,
    ],
    queryFn: () =>
      catalogosApi.vehicular(
        "cilindraje",
        formData.marca &&
          formData.modelo &&
          formData.motor &&
          selectedTipoVehiculoId
          ? {
              marca: formData.marca,
              modelo: formData.modelo,
              motor: formData.motor,
              tipoVehiculoId: selectedTipoVehiculoId,
            }
          : {},
      ),
    enabled: Boolean(
      formData.marca &&
      formData.modelo &&
      formData.motor &&
      selectedTipoVehiculoId,
    ),
  });

  const { data: clienteMatches = [] } = useQuery({
    queryKey: ["clientes", "vehiculo-picker", clienteSearch],
    queryFn: async () => {
      if (clienteSearch.length < 2) return [];

      if (navigator.onLine) {
        try {
          return await clientesApi.search(clienteSearch);
        } catch (error) {
          console.warn("Using local client cache for vehicle picker", error);
        }
      }

      const term = clienteSearch.trim().toLowerCase();
      return db.clientes
        .filter((cliente) => {
          const composite = [
            cliente.nombre,
            cliente.tarjeta,
            cliente.nit,
            cliente.telefono,
            cliente.celular,
          ]
            .filter(Boolean)
            .join(" ")
            .toLowerCase();
          return composite.includes(term);
        })
        .limit(8)
        .toArray();
    },
    enabled: clienteSearch.length >= 2,
  });

  const catalogQuickAdd = useMutation({
    mutationFn: async ({
      tipo,
      nombre,
    }: {
      tipo: "marca" | "modelo" | "motor" | "cilindraje";
      nombre: string;
    }) => {
      const payload: any = {
        tipo,
        nombre,
        tipoVehiculoId: Number(formData.tipoVehiculoId),
      };
      if (tipo === "modelo") payload.marca = formData.marca;
      if (tipo === "motor") {
        payload.marca = formData.marca;
        payload.modelo = formData.modelo;
      }
      if (tipo === "cilindraje") {
        payload.marca = formData.marca;
        payload.modelo = formData.modelo;
        payload.motor = formData.motor;
      }
      return catalogosApi.createVehicular(payload);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["catalogos", "vehicular"] });
      toast({ variant: "success", title: "Catálogo actualizado" });
    },
    onError: (error: any) =>
      toast({
        variant: "destructive",
        title: "Error",
        description: error.message || "No se pudo guardar en catálogo",
      }),
  });

  const saveMutation = useMutation({
    mutationFn: async () => {
      if (!formData.marca.trim() || !formData.modelo.trim()) {
        throw new Error(
          "Selecciona marca y modelo antes de guardar el vehículo.",
        );
      }

      const clienteIds = formData.clienteIds
        .split(",")
        .map((value) => value.trim())
        .filter(Boolean);

      const payload = {
        placa: formData.placa.trim().toUpperCase(),
        marca: formData.marca.trim() || undefined,
        modelo: formData.modelo.trim() || undefined,
        anio: formData.anio ? Number(formData.anio) : undefined,
        motor: formData.motor.trim() || undefined,
        cilindraje: formData.cilindraje.trim() || undefined,
        color: formData.color.trim() || undefined,
        tipoVehiculoId: Number(formData.tipoVehiculoId),
        clienteIds,
      };

      if (editing?.serverId) {
        return vehiculosApi.update(Number(editing.serverId), payload);
      }

      return createVehiculoWithOffline(payload);
    },
    onSuccess: (result: any) => {
      queryClient.invalidateQueries({ queryKey: ["vehiculos"] });
      toast({
        variant: "success",
        title: result?.offlineQueued
          ? "Vehículo guardado sin conexión"
          : "Vehículo guardado",
        description: result?.offlineQueued
          ? "Se sincronizará automáticamente al reconectar."
          : "Cambios guardados correctamente.",
      });
      resetForm();
    },
    onError: (error: any) =>
      toast({
        variant: "destructive",
        title: "Error",
        description: error.message || "No se pudo guardar el vehículo",
      }),
  });

  const canSubmit = Boolean(
    formData.placa.trim() &&
    formData.tipoVehiculoId &&
    formData.marca.trim() &&
    formData.modelo.trim(),
  );
  const vehiculos = useMemo(() => vehiculosData?.data ?? [], [vehiculosData]);
  const vehiculosSource = useMemo(
    () => vehiculosSourceData?.data ?? [],
    [vehiculosSourceData],
  );
  const total = vehiculosData?.total || 0;
  const showingCount = vehiculos.length;
  const currentPage = vehiculosData?.page || page;
  const totalPages = vehiculosData?.totalPages || 1;

  const vehiculosPorTipo = useMemo(() => {
    if (!formData.tipoVehiculoId) return vehiculosSource;
    return vehiculosSource.filter(
      (vehiculo: any) =>
        String(vehiculo?.tipoVehiculoId || "") === formData.tipoVehiculoId,
    );
  }, [vehiculosSource, formData.tipoVehiculoId]);

  const marcasPorTipo = useMemo(
    () =>
      toOptionList(vehiculosPorTipo.map((vehiculo: any) => vehiculo?.marca)),
    [vehiculosPorTipo],
  );
  const modelosPorTipoYMarca = useMemo(
    () =>
      toOptionList(
        vehiculosPorTipo
          .filter(
            (vehiculo: any) =>
              String(vehiculo?.marca || "").toLowerCase() ===
              formData.marca.toLowerCase(),
          )
          .map((vehiculo: any) => vehiculo?.modelo),
      ),
    [vehiculosPorTipo, formData.marca],
  );
  const motoresPorTipoMarcaModelo = useMemo(
    () =>
      toOptionList(
        vehiculosPorTipo
          .filter(
            (vehiculo: any) =>
              String(vehiculo?.marca || "").toLowerCase() ===
                formData.marca.toLowerCase() &&
              String(vehiculo?.modelo || "").toLowerCase() ===
                formData.modelo.toLowerCase(),
          )
          .map((vehiculo: any) => vehiculo?.motor),
      ),
    [vehiculosPorTipo, formData.marca, formData.modelo],
  );
  const cilindrajesPorTipoMarcaModeloMotor = useMemo(
    () =>
      toOptionList(
        vehiculosPorTipo
          .filter(
            (vehiculo: any) =>
              String(vehiculo?.marca || "").toLowerCase() ===
                formData.marca.toLowerCase() &&
              String(vehiculo?.modelo || "").toLowerCase() ===
                formData.modelo.toLowerCase() &&
              String(vehiculo?.motor || "").toLowerCase() ===
                formData.motor.toLowerCase(),
          )
          .map((vehiculo: any) => vehiculo?.cilindraje),
      ),
    [vehiculosPorTipo, formData.marca, formData.modelo, formData.motor],
  );

  const marcaOptions = useMemo(
    () =>
      withCurrentOption(
        mergeOptions(uniqByNombre(marcas), marcasPorTipo),
        formData.marca,
      ),
    [marcas, marcasPorTipo, formData.marca],
  );
  const modeloOptions = useMemo(
    () =>
      withCurrentOption(
        mergeOptions(uniqByNombre(modelos), modelosPorTipoYMarca),
        formData.modelo,
      ),
    [modelos, modelosPorTipoYMarca, formData.modelo],
  );
  const motorOptions = useMemo(
    () =>
      withCurrentOption(
        mergeOptions(uniqByNombre(motores), motoresPorTipoMarcaModelo),
        formData.motor,
      ),
    [motores, motoresPorTipoMarcaModelo, formData.motor],
  );
  const cilindrajeOptions = useMemo(
    () =>
      withCurrentOption(
        mergeOptions(
          uniqByNombre(cilindrajes),
          cilindrajesPorTipoMarcaModeloMotor,
        ),
        formData.cilindraje,
      ),
    [cilindrajes, cilindrajesPorTipoMarcaModeloMotor, formData.cilindraje],
  );

  const selectedClienteIds = useMemo(
    () =>
      formData.clienteIds
        .split(",")
        .map((value) => value.trim())
        .filter(Boolean),
    [formData.clienteIds],
  );

  /*
   * `vehiculo.clienteIds` y `formData.clienteIds` solo guardan la tarjeta del
   * cliente, no su nombre. Antes esto se mostraba tal cual ("00042"), algo
   * que no le dice nada al mecánico. `db.clientes` ya tiene el nombre de
   * (casi) todos los clientes cacheado localmente por el bootstrap offline,
   * así que lo resolvemos ahí en vez de pedirle un endpoint nuevo al backend.
   * Si una tarjeta no está en caché todavía, se sigue mostrando la tarjeta
   * como respaldo — nunca queda un chip vacío.
   */
  const clienteTarjetasAResolver = useMemo(() => {
    const tarjetas = new Set<string>(selectedClienteIds);
    vehiculos.forEach((vehiculo: any) => {
      (vehiculo.clienteIds || []).forEach((tarjeta: string) => tarjetas.add(tarjeta));
    });
    return Array.from(tarjetas);
  }, [selectedClienteIds, vehiculos]);

  const { data: clienteNombresPorTarjeta } = useQuery({
    queryKey: ["clientes", "nombres-por-tarjeta", clienteTarjetasAResolver],
    queryFn: async () => {
      const registros = await db.clientes.bulkGet(clienteTarjetasAResolver);
      const mapa = new Map<string, string>();
      registros.forEach((cliente, index) => {
        if (cliente?.nombre) {
          mapa.set(clienteTarjetasAResolver[index], cliente.nombre);
        }
      });
      return mapa;
    },
    enabled: clienteTarjetasAResolver.length > 0,
    placeholderData: (previous) => previous,
    staleTime: 60_000,
  });

  const getClienteLabel = (tarjeta: string) => clienteNombresPorTarjeta?.get(tarjeta) || tarjeta;

  const removeClienteId = (id: string) => {
    const next = selectedClienteIds.filter((value) => value !== id);
    setFormData({ ...formData, clienteIds: next.join(", ") });
  };

  const addClienteId = (id: string) => {
    if (selectedClienteIds.includes(id)) return;
    setFormData({
      ...formData,
      clienteIds: [...selectedClienteIds, id].join(", "),
    });
  };

  const createCatalogItem = async (
    tipo: "marca" | "modelo" | "motor" | "cilindraje",
  ) => {
    if (tipo !== "marca" && !formData.marca) {
      toast({
        variant: "destructive",
        title: "Falta marca",
        description: "Selecciona marca antes de crear este catálogo.",
      });
      return;
    }
    if ((tipo === "motor" || tipo === "cilindraje") && !formData.modelo) {
      toast({
        variant: "destructive",
        title: "Falta modelo",
        description: "Selecciona modelo antes de crear este catálogo.",
      });
      return;
    }
    if (tipo === "cilindraje" && !formData.motor) {
      toast({
        variant: "destructive",
        title: "Falta motor",
        description: "Selecciona motor antes de crear este catálogo.",
      });
      return;
    }

    // Etiquetas en palabras del taller: "Nueva marca", no "Nuevo marca".
    const etiquetas = {
      marca: { titulo: "Nueva marca", campo: "Nombre de la marca", ejemplo: "Toyota" },
      modelo: { titulo: "Nuevo modelo", campo: "Nombre del modelo", ejemplo: "Hilux" },
      motor: { titulo: "Nuevo motor", campo: "Nombre del motor", ejemplo: "2.4 Diesel" },
      cilindraje: { titulo: "Nuevo cilindraje", campo: "Cilindraje", ejemplo: "2400 cc" },
    } as const;

    const etiqueta = etiquetas[tipo];

    const clean = await prompt({
      title: etiqueta.titulo,
      description: "Se agrega al catálogo y queda disponible para las próximas fichas.",
      label: etiqueta.campo,
      placeholder: `Por ejemplo: ${etiqueta.ejemplo}`,
      confirmLabel: "Agregar",
      validate: (value) =>
        value.length < 2 ? "Escribí al menos 2 letras." : null,
    });

    if (!clean) return;

    if (tipo === "marca")
      setFormData({
        ...formData,
        marca: clean,
        modelo: "",
        motor: "",
        cilindraje: "",
      });
    if (tipo === "modelo")
      setFormData({ ...formData, modelo: clean, motor: "", cilindraje: "" });
    if (tipo === "motor")
      setFormData({ ...formData, motor: clean, cilindraje: "" });
    if (tipo === "cilindraje") setFormData({ ...formData, cilindraje: clean });

    catalogQuickAdd.mutate({ tipo, nombre: clean });
  };

  return (
    <div className="min-h-full pb-16 md:pb-10">
      <main className="mx-auto flex max-w-6xl flex-col gap-6">
        <DashboardPageIntro
          title="Vehículos"
          description="El flujo de registro ahora destaca la ficha técnica, los clientes vinculados y la lista paginada. La caché local se lee primero y luego se refresca si hay internet."
          icon={Car}
          tone="slate"
          badge={searchTerm.trim() ? "Búsqueda activa" : "Parque vehicular"}
          actions={
            <Button
              onClick={() => {
                if (showForm) {
                  resetForm();
                } else {
                  setShowForm(true);
                }
              }}
              className="w-full sm:w-auto"
            >
              <Plus className="mr-2 h-4 w-4" />
              {showForm ? "Cancelar" : "Nuevo vehículo"}
            </Button>
          }
          stats={[
            {
              label: "Vehículos totales",
              value: total,
              hint: "Conteo general del módulo",
              icon: Car,
            },
            {
              label: "En esta página",
              value: showingCount,
              hint: "Resultados visibles ahora",
              icon: Search,
            },
          ]}
          filters={
            <DashboardToolbar
              searchValue={searchTerm}
              onSearchChange={(value) => {
                setSearchTerm(value);
                setPage(1);
              }}
              searchPlaceholder="Buscar por placa, marca o modelo..."
            />
          }
        />

        {showForm ? (
          <DashboardSection
            title={editing ? "Editar vehículo" : "Registrar vehículo"}
            description="Completa tipo, ficha técnica y clientes vinculados en un solo bloque."
          >
            <div className="space-y-4">
              <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
                <Field label="Placa" htmlFor="vehiculo-placa" required>
                  <Input
                    value={formData.placa}
                    onChange={(e) =>
                      setFormData({
                        ...formData,
                        placa: e.target.value.toUpperCase(),
                      })
                    }
                    className="h-11"
                    disabled={!!editing}
                  />
                </Field>
                <Select
                  value={formData.tipoVehiculoId}
                  onValueChange={(value) =>
                    setFormData({
                      ...formData,
                      tipoVehiculoId: value,
                      marca: "",
                      modelo: "",
                      motor: "",
                      cilindraje: "",
                    })
                  }
                >
                  <SelectTrigger aria-label="Tipo de vehículo">
                    <SelectValue placeholder="Tipo de vehículo *" />
                  </SelectTrigger>
                  <SelectContent>
                    {(tiposVehiculo || []).map((tipo: any) => (
                      <SelectItem key={tipo.id} value={String(tipo.id)}>
                        {tipo.nombre}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
                <div className="space-y-2">
                  <div className="flex items-center justify-between">
                    <label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                      Marca *
                    </label>
                    <button
                      type="button"
                      className="text-xs font-semibold text-primary hover:underline"
                      onClick={() => createCatalogItem("marca")}
                    >
                      + Nuevo
                    </button>
                  </div>
                  <Select
                    value={formData.marca}
                    onValueChange={(value) =>
                      setFormData({
                        ...formData,
                        marca: value,
                        modelo: "",
                        motor: "",
                        cilindraje: "",
                      })
                    }
                    disabled={!formData.tipoVehiculoId}
                  >
                    <SelectTrigger aria-label="Marca">
                      <SelectValue
                        placeholder={
                          formData.tipoVehiculoId
                            ? "Seleccionar marca"
                            : "Primero selecciona tipo de vehículo"
                        }
                      />
                    </SelectTrigger>
                    <SelectContent>
                      {marcaOptions.map((marca: any) => (
                        <SelectItem key={marca.id} value={marca.nombre}>
                          {marca.nombre}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>

                <div className="space-y-2">
                  <div className="flex items-center justify-between">
                    <label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                      Modelo *
                    </label>
                    <button
                      type="button"
                      className="text-xs font-semibold text-primary hover:underline"
                      onClick={() => createCatalogItem("modelo")}
                    >
                      + Nuevo
                    </button>
                  </div>
                  <Select
                    value={formData.modelo}
                    onValueChange={(value) =>
                      setFormData({
                        ...formData,
                        modelo: value,
                        motor: "",
                        cilindraje: "",
                      })
                    }
                    disabled={!formData.marca}
                  >
                    <SelectTrigger aria-label="Modelo">
                      <SelectValue
                        placeholder={
                          formData.marca ? "Seleccionar modelo" : "Primero selecciona marca"
                        }
                      />
                    </SelectTrigger>
                    <SelectContent>
                      {modeloOptions.map((modelo: any) => (
                        <SelectItem key={modelo.id} value={modelo.nombre}>
                          {modelo.nombre}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </div>

              <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
                <Field label="Año" htmlFor="vehiculo-anio">
                  <Input
                    type="number"
                    inputMode="numeric"
                    value={formData.anio}
                    onChange={(e) =>
                      setFormData({ ...formData, anio: e.target.value })
                    }
                    className="h-11"
                  />
                </Field>
                <Field label="Color" htmlFor="vehiculo-color">
                  <Input
                    value={formData.color}
                    onChange={(e) =>
                      setFormData({ ...formData, color: e.target.value })
                    }
                    className="h-11"
                  />
                </Field>
              </div>

              <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
                <div className="space-y-2">
                  <div className="flex items-center justify-between">
                    <label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                      SERIE MOTOR
                    </label>
                    <button
                      type="button"
                      className="text-xs font-semibold text-primary hover:underline"
                      onClick={() => createCatalogItem("motor")}
                    >
                      + Nuevo
                    </button>
                  </div>
                  <Select
                    value={formData.motor}
                    onValueChange={(value) =>
                      setFormData({
                        ...formData,
                        motor: value,
                        cilindraje: "",
                      })
                    }
                    disabled={!formData.marca || !formData.modelo}
                  >
                    <SelectTrigger aria-label="Serie motor">
                      <SelectValue
                        placeholder={
                          formData.modelo ? "Seleccionar serie motor" : "Primero selecciona modelo"
                        }
                      />
                    </SelectTrigger>
                    <SelectContent>
                      {motorOptions.map((motor: any) => (
                        <SelectItem key={motor.id} value={motor.nombre}>
                          {motor.nombre}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>

                <div className="space-y-2">
                  <div className="flex items-center justify-between">
                    <label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                      C.C.
                    </label>
                    <button
                      type="button"
                      className="text-xs font-semibold text-primary hover:underline"
                      onClick={() => createCatalogItem("cilindraje")}
                    >
                      + Nuevo
                    </button>
                  </div>
                  <Select
                    value={formData.cilindraje}
                    onValueChange={(value) =>
                      setFormData({ ...formData, cilindraje: value })
                    }
                    disabled={!formData.motor}
                  >
                    <SelectTrigger aria-label="Cilindraje">
                      <SelectValue
                        placeholder={
                          formData.motor ? "Seleccionar C.C." : "Primero selecciona serie motor"
                        }
                      />
                    </SelectTrigger>
                    <SelectContent>
                      {cilindrajeOptions.map((cilindraje: any) => (
                        <SelectItem key={cilindraje.id} value={cilindraje.nombre}>
                          {cilindraje.nombre}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              </div>

              <div className="space-y-2 rounded-xl border border-border bg-muted p-4">
                <p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                  Clientes vinculados
                </p>
                <Input
                  placeholder="Buscar cliente por nombre, NIT, teléfono o tarjeta..."
                  value={clienteSearch}
                  onChange={(e) => setClienteSearch(e.target.value)}
                  className="h-10"
                />

                {selectedClienteIds.length > 0 ? (
                  <div className="flex flex-wrap gap-2">
                    {selectedClienteIds.map((id) => (
                      <span
                        key={id}
                        className="inline-flex items-center gap-1 rounded-full bg-primary-soft px-3 py-1 text-xs font-semibold text-primary"
                      >
                        {getClienteLabel(id)}
                        <button
                          type="button"
                          onClick={() => removeClienteId(id)}
                          aria-label={`Quitar cliente ${getClienteLabel(id)} de la lista`}
                          className="-mr-1 flex h-7 w-7 items-center justify-center rounded-full hover:bg-primary/20"
                        >
                          <X className="h-3 w-3" />
                        </button>
                      </span>
                    ))}
                  </div>
                ) : null}
                {clienteMatches.length > 0 ? (
                  <div className="max-h-36 overflow-auto rounded-xl border border-border bg-surface">
                    {clienteMatches.slice(0, 8).map((cliente: any) => (
                      <button
                        key={cliente.tarjeta}
                        type="button"
                        className="w-full border-b border-border px-3 py-2 text-left text-sm hover:bg-muted"
                        onClick={() => addClienteId(cliente.tarjeta)}
                      >
                        <span className="font-semibold">{cliente.nombre}</span>
                        <span className="ml-2 text-xs text-muted-foreground">
                          {cliente.tarjeta}
                        </span>
                      </button>
                    ))}
                  </div>
                ) : null}
              </div>

              <Button
                className="h-11 w-full"
                disabled={!canSubmit || saveMutation.isPending}
                onClick={() => saveMutation.mutate()}
              >
                {saveMutation.isPending ? "Guardando..." : "Guardar vehículo"}
              </Button>
            </div>
          </DashboardSection>
        ) : null}
        {isLoading ? (
          <DashboardSection
            title="Listado"
            description="Cargando vehículos disponibles."
          >
            <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
              {Array.from({ length: 6 }).map((_, index) => (
                <div key={index} className="rounded-xl border border-border p-4">
                  <SkeletonListRow className="px-0" />
                </div>
              ))}
            </div>
          </DashboardSection>
        ) : isError ? (
          <DashboardSection title="Listado" description="No se pudo cargar el listado de vehículos.">
            <ErrorState onRetry={() => refetch()} description="No se pudo cargar la lista de vehículos guardada en este dispositivo." />
          </DashboardSection>
        ) : vehiculos.length === 0 ? (
          <DashboardEmptyState
            title={searchTerm.trim() ? "No se encontraron vehículos" : "No hay vehículos registrados"}
            description={
              searchTerm.trim()
                ? "Prueba otro criterio de búsqueda para ampliar los resultados."
                : "Registra el primer vehículo para poder vincularlo a clientes y OTs."
            }
            icon={Car}
            action={
              !searchTerm.trim() ? (
                <Button onClick={() => setShowForm(true)}>
                  <Plus className="mr-2 h-4 w-4" />
                  Crear el primero
                </Button>
              ) : undefined
            }
          />
        ) : (
          <DashboardSection
            title="Listado de vehículos"
            description="Tarjetas resumidas para ubicar placa, ficha técnica y clientes asociados sin desorden visual."
          >
            <div className="space-y-4">
              <PaginatedListFooter
                page={currentPage}
                limit={limit}
                total={total}
                totalPages={totalPages}
                itemLabel="vehículos"
                onPageChange={setPage}
                onLimitChange={(nextLimit) => {
                  setLimit(nextLimit);
                  setPage(1);
                }}
                pageSizeOptions={PAGE_SIZE_OPTIONS}
              />

              {/* Mobile: filas táctiles compactas. Desde md, tarjetas: la ficha técnica y los
                  clientes vinculados no caben en columnas de tabla sin desordenarse. */}
              <div className="overflow-hidden rounded-xl border border-border md:hidden">
                {vehiculos.map((vehiculo: any) => (
                  <DashboardListRow
                    key={vehiculo.id || vehiculo.localId}
                    icon={<Car className="h-4 w-4" />}
                    title={`${vehiculo.placa} - ${vehiculo.marca || "Sin marca"} ${vehiculo.modelo || ""}`}
                    meta={`Año ${vehiculo.anio || "N/A"} | ${(vehiculo.clienteIds || []).length} cliente(s) vinculado(s)`}
                    actions={
                      <Button
                        variant="ghost"
                        size="icon"
                        aria-label="Editar vehículo"
                        onClick={() => {
                          setEditing(vehiculo);
                          setShowForm(true);
                          setFormData({
                            placa: vehiculo.placa || "",
                            marca: vehiculo.marca || "",
                            modelo: vehiculo.modelo || "",
                            anio: vehiculo.anio ? String(vehiculo.anio) : "",
                            motor: vehiculo.motor || "",
                            cilindraje: vehiculo.cilindraje || "",
                            color: vehiculo.color || "",
                            tipoVehiculoId: vehiculo.tipoVehiculoId ? String(vehiculo.tipoVehiculoId) : "",
                            clienteIds: (vehiculo.clienteIds || []).join(", "),
                          });
                        }}
                      >
                        <Pencil className="h-4 w-4" />
                      </Button>
                    }
                  />
                ))}
              </div>

              <div className="hidden gap-4 md:grid md:grid-cols-2 xl:grid-cols-3">
                {vehiculos.map((vehiculo: any) => {
                  const clienteIds = vehiculo.clienteIds || [];
                  const visibleClienteIds = clienteIds.slice(0, 2);
                  const hiddenClienteCount = Math.max(
                    0,
                    clienteIds.length - visibleClienteIds.length,
                  );

                  return (
                    <Card
                      key={vehiculo.id || vehiculo.localId}
                      className="border-border transition-transform duration-150 ease-out hover:-translate-y-0.5 hover:shadow-md"
                    >
                      <CardContent className="space-y-3 p-4">
                        <div className="flex items-center justify-between gap-3">
                          <span className="flex items-center gap-2 text-base font-bold tracking-wide text-foreground">
                            <Car size={18} className="text-primary" />
                            {vehiculo.placa}
                          </span>
                          <Badge variant="neutral">{vehiculo.anio || "N/A"}</Badge>
                        </div>

                        <div className="space-y-1 text-sm">
                          <p className="font-bold text-foreground">
                            {vehiculo.marca || "Sin marca"}{" "}
                            {vehiculo.modelo || ""}
                          </p>
                          <p className="text-muted-foreground">
                            Serie motor: {vehiculo.motor || "-"} | C.C.:{" "}
                            {vehiculo.cilindraje || "-"}
                          </p>
                          <p className="text-muted-foreground">
                            Color: {vehiculo.color || "-"}
                          </p>
                        </div>

                        <div className="rounded-xl border border-border bg-muted p-3">
                          <div className="mb-2 flex items-center gap-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                            <Users className="h-3.5 w-3.5" />
                            Clientes vinculados
                          </div>
                          {clienteIds.length === 0 ? (
                            <p className="text-sm text-muted-foreground">
                              Sin clientes asociados
                            </p>
                          ) : (
                            <div className="flex flex-wrap gap-2">
                              {visibleClienteIds.map((id: string) => (
                                <span
                                  key={id}
                                  className="rounded-full bg-surface px-2.5 py-1 text-xs font-semibold text-foreground ring-1 ring-border"
                                >
                                  {getClienteLabel(id)}
                                </span>
                              ))}
                              {hiddenClienteCount > 0 ? (
                                <span className="rounded-full bg-primary-soft px-2.5 py-1 text-xs font-semibold text-primary">
                                  +{hiddenClienteCount} más
                                </span>
                              ) : null}
                            </div>
                          )}
                        </div>

                        <div className="flex justify-end">
                          <Button
                            variant="outline"
                            size="sm"
                            className="rounded-xl"
                            onClick={() => {
                              setEditing(vehiculo);
                              setShowForm(true);
                              setFormData({
                                placa: vehiculo.placa || "",
                                marca: vehiculo.marca || "",
                                modelo: vehiculo.modelo || "",
                                anio: vehiculo.anio
                                  ? String(vehiculo.anio)
                                  : "",
                                motor: vehiculo.motor || "",
                                cilindraje: vehiculo.cilindraje || "",
                                color: vehiculo.color || "",
                                tipoVehiculoId: vehiculo.tipoVehiculoId
                                  ? String(vehiculo.tipoVehiculoId)
                                  : "",
                                clienteIds: (vehiculo.clienteIds || []).join(
                                  ", ",
                                ),
                              });
                            }}
                          >
                            <Pencil className="mr-1 h-4 w-4" />
                            Editar
                          </Button>
                        </div>
                      </CardContent>
                    </Card>
                  );
                })}
              </div>

              {totalPages > 1 ? (
                <PaginatedListFooter
                  page={currentPage}
                  limit={limit}
                  total={total}
                  totalPages={totalPages}
                  itemLabel="vehículos"
                  onPageChange={setPage}
                  onLimitChange={(nextLimit) => {
                    setLimit(nextLimit);
                    setPage(1);
                  }}
                  pageSizeOptions={PAGE_SIZE_OPTIONS}
                />
              ) : null}
            </div>
          </DashboardSection>
        )}
      </main>
    </div>
  );
}
