'use client';

import { DashboardEmptyState, DashboardListRow, DashboardPageIntro, DashboardSection } from '@/components/dashboard-page';
import { Badge, type EstadoOT } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu';
import { Input } from '@/components/ui/input';
import { SkeletonListRow } from '@/components/ui/skeleton';
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { useFlagsConfiguracion } from '@/hooks/use-flags-configuracion';
import { useToast } from '@/hooks/use-toast';
import { historialApi } from '@/lib/api';
import { cacheRemoteClientes } from '@/lib/offline-clientes';
import { getHistorialByClienteLocal, getHistorialByPlacaLocal } from '@/lib/offline-historial';
import { cacheRemoteOtList } from '@/lib/offline-ots';
import { cacheRemoteVehiculos } from '@/lib/offline-vehiculos';
import { formatCurrency, formatDate, getEstadoLabel } from '@/lib/utils';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { Calendar, Car, Eye, FileText, Gauge, History, Image as ImageIcon, MoreVertical, PenTool, Receipt, Search, ShieldAlert, User } from 'lucide-react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useRef, useState } from 'react';

const ESTADOS_OT: readonly EstadoOT[] = ['borrador', 'en_proceso', 'cotizada', 'aprobada', 'terminada', 'facturada', 'entregada'];

function isEstadoOT(value: string): value is EstadoOT {
  return (ESTADOS_OT as readonly string[]).includes(value);
}

function EstadoOtBadge({ estado }: { estado: string }) {
  if (isEstadoOT(estado)) {
    return (
      <Badge variant="estado" estado={estado}>
        {getEstadoLabel(estado)}
      </Badge>
    );
  }
  return <Badge variant="outline">{getEstadoLabel(estado)}</Badge>;
}

type SearchType = 'general' | 'cliente' | 'placa';
type HistorialClienteData = Awaited<ReturnType<typeof getHistorialByClienteLocal>>;
type HistorialPlacaData = Awaited<ReturnType<typeof getHistorialByPlacaLocal>>;
type HistorialSearchData = { q: string; clientes: any[]; vehiculos: any[] };
type HistorialData = HistorialClienteData | HistorialPlacaData | HistorialSearchData;

function isSearchData(data: HistorialData | null | undefined): data is HistorialSearchData {
  return Boolean(data && Array.isArray((data as any).clientes) && Array.isArray((data as any).vehiculos) && (data as any).ots === undefined);
}

function normalizeSearchForMode(value: string, mode: SearchType) {
  const trimmed = value.trim();
  return mode === 'placa' ? trimmed.toUpperCase() : trimmed;
}

export default function HistorialPage() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const queryClient = useQueryClient();
  const flags = useFlagsConfiguracion();
  const { toast } = useToast();
  const lastRefreshKey = useRef('');
  const hasShownSyncError = useRef(false);
  const [searchType, setSearchType] = useState<SearchType>(searchParams.get('placa') ? 'placa' : searchParams.get('cliente') ? 'cliente' : 'general');
  const [searchValue, setSearchValue] = useState(searchParams.get('cliente') || searchParams.get('placa') || '');
  const normalizedSearchValue = normalizeSearchForMode(searchValue, searchType);

  const { data, isLoading, refetch } = useQuery<HistorialData | null>({
    queryKey: ['historial', searchType, normalizedSearchValue],
    queryFn: async () => {
      const refreshKey = `${searchType}:${normalizedSearchValue.toLowerCase()}`;

      if (searchType === 'general') {
        if (!navigator.onLine) {
          return { q: normalizedSearchValue, clientes: [], vehiculos: [] };
        }

        return historialApi.search(normalizedSearchValue);
      }

      if (navigator.onLine && normalizedSearchValue.length >= 2 && lastRefreshKey.current !== refreshKey) {
        lastRefreshKey.current = refreshKey;

        void (async () => {
          try {
            const remote = searchType === 'cliente'
              ? await historialApi.byCliente(normalizedSearchValue)
              : await historialApi.byPlaca(normalizedSearchValue);

            if (remote?.cliente) {
              await cacheRemoteClientes([remote.cliente]);
            }

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

            if (remote?.vehiculo) {
              await cacheRemoteVehiculos([remote.vehiculo]);
            }

            if (Array.isArray(remote?.ots) && remote.ots.length > 0) {
              await cacheRemoteOtList(remote.ots);
            }

            hasShownSyncError.current = false;
            await queryClient.invalidateQueries({ queryKey: ['historial', searchType, normalizedSearchValue] });
          } catch (error) {
            console.warn('Using local history cache', error);
            if (!hasShownSyncError.current) {
              hasShownSyncError.current = true;
              toast({
                variant: 'destructive',
                title: 'No se pudo actualizar',
                description: 'Mostrando historial guardado en este dispositivo. Revisa la conexión con el servidor.',
              });
            }
          }
        })();
      }

      return searchType === 'cliente'
        ? getHistorialByClienteLocal(normalizedSearchValue.toUpperCase())
        : getHistorialByPlacaLocal(normalizedSearchValue.toUpperCase());
    },
    enabled: normalizedSearchValue.length >= 2,
  });

  const searchData = searchType === 'general' && isSearchData(data) ? data : undefined;
  const clienteData = searchType === 'cliente' && !isSearchData(data) ? (data as HistorialClienteData | undefined) : undefined;
  const placaData = searchType === 'placa' && !isSearchData(data) ? (data as HistorialPlacaData | undefined) : undefined;
  const exactData = !isSearchData(data) ? data as HistorialClienteData | HistorialPlacaData | undefined : undefined;

  const handleSearch = (event: React.FormEvent) => {
    event.preventDefault();
    if (normalizedSearchValue.length >= 2) {
      void refetch();
    }
  };

  const openClienteHistory = (tarjeta: string) => {
    setSearchType('cliente');
    setSearchValue(tarjeta);
  };

  const openVehicleHistory = (placa: string) => {
    setSearchType('placa');
    setSearchValue(placa.toUpperCase());
  };

  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="Historial"
          description="Busca por nombre, NIT, tarjeta, placa, marca o modelo. Luego abre el historial exacto del cliente o del vehículo."
          icon={History}
          tone="emerald"
          badge={searchType === 'general' ? 'Búsqueda general' : searchType === 'cliente' ? 'Consulta por cliente' : 'Consulta por placa'}
          onBack={() => router.push('/dashboard')}
          filters={
            <Card className="border-border bg-surface">
              <CardContent className="space-y-4 p-4">
                <Tabs
                  value={searchType}
                  onValueChange={(value) => {
                    setSearchType(value as SearchType);
                    setSearchValue('');
                  }}
                >
                  <TabsList variant="segmented" className="w-full">
                    <TabsTrigger value="general">
                      <Search className="mr-2 h-4 w-4" />
                      Todo
                    </TabsTrigger>
                    <TabsTrigger value="cliente">
                      <User className="mr-2 h-4 w-4" />
                      Cliente exacto
                    </TabsTrigger>
                    <TabsTrigger value="placa">
                      <Car className="mr-2 h-4 w-4" />
                      Vehículo exacto
                    </TabsTrigger>
                  </TabsList>
                </Tabs>

                <form onSubmit={handleSearch} className="space-y-2">
                  <div className="relative">
                    <Search className="absolute left-3 top-1/2 -translate-y-1/2 text-subtle-foreground" size={18} />
                    <Input
                      placeholder={searchType === 'general' ? 'Nombre, NIT, placa, marca o modelo' : searchType === 'cliente' ? 'Tarjeta exacta del cliente' : 'Placa exacta del vehículo'}
                      value={searchValue}
                      onChange={(event) => setSearchValue(searchType === 'placa' ? event.target.value.toUpperCase() : event.target.value)}
                      className="h-11 pl-10"
                    />
                  </div>
                  <p className="text-sm text-muted-foreground">
                    {searchType === 'general'
                      ? 'Abre el ojo para ver el historial completo de un cliente o de un vehículo.'
                      : searchType === 'cliente'
                        ? 'Usa consulta exacta si ya sabes la tarjeta. Para nombre o NIT usa Todo.'
                        : 'Usa consulta exacta si ya sabes la placa. Para marca o modelo usa Todo.'}
                  </p>
                </form>
              </CardContent>
            </Card>
          }
          stats={
            exactData
              ? [
                  { label: 'OTs encontradas', value: exactData.totalOts || 0, hint: 'Coinciden con la búsqueda', icon: FileText },
                  { label: 'Total cotizado', value: formatCurrency(exactData.totalCotizado || 0), hint: 'Acumulado histórico', icon: Calendar },
                  {
                    label: searchType === 'cliente' ? 'Vehículos' : 'Último km',
                    value:
                      searchType === 'cliente'
                        ? clienteData?.vehiculos?.length || 0
                        : placaData?.ultimoKm
                          ? `${Number(placaData.ultimoKm).toLocaleString()} km`
                          : 'Sin dato',
                    hint: searchType === 'cliente' ? 'Asociados al cliente' : 'Último registro disponible',
                    icon: searchType === 'cliente' ? Car : Gauge,
                  },
                ]
              : []
          }
        />

        {isLoading ? (
          <DashboardSection title="Resultados" description="Consultando el historial solicitado.">
            <div className="divide-y divide-border">
              {Array.from({ length: 3 }).map((_, index) => (
                <SkeletonListRow key={index} />
              ))}
            </div>
          </DashboardSection>
        ) : !data ? (
          <DashboardEmptyState title="Empieza con una búsqueda" description="Escribe al menos 2 caracteres para consultar el historial." icon={Search} />
        ) : searchType === 'general' && searchData ? (
          <div className="grid gap-6 xl:grid-cols-2">
            <DashboardSection title="Clientes encontrados" description="Coincidencias por nombre, NIT o tarjeta.">
              {searchData.clientes.length ? (
                <div className="overflow-hidden rounded-xl border border-border">
                  {searchData.clientes.map((cliente: any) => (
                    <DashboardListRow
                      key={cliente.tarjeta}
                      icon={<User className="h-4 w-4" />}
                      title={cliente.nombre}
                      meta={`${cliente.tarjeta} · NIT: ${cliente.nit || 'CF'} · ${cliente.totalOts || 0} OT(s)`}
                      onClick={() => openClienteHistory(cliente.tarjeta)}
                      actions={
                        <Button variant="ghost" size="icon" aria-label="Ver historial del cliente" onClick={() => openClienteHistory(cliente.tarjeta)}>
                          <Eye className="h-4 w-4" />
                        </Button>
                      }
                    />
                  ))}
                </div>
              ) : (
                <DashboardEmptyState title="Sin clientes" description="No hay clientes que coincidan con esta búsqueda." icon={User} className="border-none bg-muted shadow-none" />
              )}
            </DashboardSection>

            <DashboardSection title="Vehículos encontrados" description="Coincidencias por placa, marca o modelo.">
              {searchData.vehiculos.length ? (
                <div className="overflow-hidden rounded-xl border border-border">
                  {searchData.vehiculos.map((vehiculo: any) => (
                    <DashboardListRow
                      key={vehiculo.id}
                      icon={<Car className="h-4 w-4" />}
                      title={<span className="uppercase tracking-wide">{vehiculo.placa}</span>}
                      meta={`${vehiculo.marca || 'Sin marca'} ${vehiculo.modelo || ''}${vehiculo.anio ? ` (${vehiculo.anio})` : ''} · ${vehiculo.totalOts || 0} OT(s)${vehiculo.ultimoKm ? ` · ${Number(vehiculo.ultimoKm).toLocaleString()} km` : ''}`}
                      onClick={() => openVehicleHistory(vehiculo.placa)}
                      actions={
                        <Button variant="ghost" size="icon" aria-label="Ver historial del vehículo" onClick={() => openVehicleHistory(vehiculo.placa)}>
                          <Eye className="h-4 w-4" />
                        </Button>
                      }
                    />
                  ))}
                </div>
              ) : (
                <DashboardEmptyState title="Sin vehículos" description="No hay placas, marcas o modelos que coincidan." icon={Car} className="border-none bg-muted shadow-none" />
              )}
            </DashboardSection>
          </div>
        ) : (
          <>
            {searchType === 'placa' && placaData?.vehiculo ? (
              <DashboardSection title="Ficha del vehículo" description="Datos clave para confirmar que estás viendo el historial correcto.">
                <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
                  <div className="rounded-xl bg-muted p-4"><p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">Placa</p><p className="mt-2 text-lg font-bold text-foreground">{placaData.vehiculo.placa}</p></div>
                  <div className="rounded-xl bg-muted p-4"><p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">Marca y modelo</p><p className="mt-2 text-lg font-bold text-foreground">{placaData.vehiculo.marca} {placaData.vehiculo.modelo}</p></div>
                  <div className="rounded-xl bg-muted p-4"><p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">Año</p><p className="mt-2 text-lg font-bold text-foreground">{placaData.vehiculo.anio || '-'}</p></div>
                  <div className="rounded-xl bg-muted p-4"><p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">Color</p><p className="mt-2 text-lg font-bold text-foreground">{placaData.vehiculo.color || '-'}</p></div>
                </div>
              </DashboardSection>
            ) : null}

            {searchType === 'cliente' && (clienteData?.vehiculos?.length || 0) > 0 ? (
              <DashboardSection title="Vehículos del cliente" description="Toca el ojo para cambiar al historial puntual del vehículo.">
                <div className="overflow-hidden rounded-xl border border-border">
                  {clienteData?.vehiculos.map((vehiculo: any) => (
                    <DashboardListRow
                      key={vehiculo.id}
                      icon={<Car className="h-4 w-4" />}
                      title={<span className="uppercase tracking-wide">{vehiculo.placa}</span>}
                      meta={`${vehiculo.marca || ''} ${vehiculo.modelo || ''}`}
                      onClick={() => openVehicleHistory(vehiculo.placa)}
                      actions={
                        <Button variant="ghost" size="icon" aria-label="Ver historial del vehículo" onClick={() => openVehicleHistory(vehiculo.placa)}>
                          <Eye className="h-4 w-4" />
                        </Button>
                      }
                    />
                  ))}
                </div>
              </DashboardSection>
            ) : null}

            <DashboardSection title="Línea de tiempo de OTs" description="Abre el detalle para ver cotización, daños, fotos, firmas y toda la orden.">
              {exactData?.ots && exactData.ots.length > 0 ? (
                <div className="space-y-3">
                  {exactData.ots.map((ot: any) => (
                    <Card key={ot.id}>
                      <CardContent className="grid gap-4 p-4 lg:grid-cols-[1fr_auto] lg:items-center">
                        <div className="min-w-0 space-y-2">
                          <div className="flex flex-wrap items-center gap-2">
                            <span className="font-semibold text-foreground">{ot.numeroOt}</span>
                            <EstadoOtBadge estado={ot.estado} />
                            {ot.totalCotizacion > 0 ? <Badge variant="success">{formatCurrency(ot.totalCotizacion)}</Badge> : null}
                          </div>
                          <div className="flex flex-wrap gap-2 text-xs text-muted-foreground">
                            <span className="inline-flex items-center gap-1 rounded-full bg-muted px-3 py-1"><Calendar size={12} />{formatDate(ot.fechaEntrada)}</span>
                            {ot.km ? <span className="inline-flex items-center gap-1 rounded-full bg-muted px-3 py-1"><Gauge size={12} />{Number(ot.km).toLocaleString()} km</span> : null}
                            {flags.usaFotos ? <span className="inline-flex items-center gap-1 rounded-full bg-muted px-3 py-1"><ImageIcon size={12} />{ot.resumen?.totalFotos || 0} fotos</span> : null}
                            {flags.usaDanos ? <span className="inline-flex items-center gap-1 rounded-full bg-muted px-3 py-1"><ShieldAlert size={12} />{ot.resumen?.totalDanos || 0} daños</span> : null}
                            {flags.usaFirmaCliente || flags.usaFirmaRecepcion ? <span className="inline-flex items-center gap-1 rounded-full bg-muted px-3 py-1"><PenTool size={12} />{ot.resumen?.tieneFirmas ? 'Con firmas' : 'Sin firmas'}</span> : null}
                            <span className="inline-flex items-center gap-1 rounded-full bg-muted px-3 py-1"><FileText size={12} />{ot.cotizacion?.lineas?.length || 0} líneas</span>
                          </div>
                          {ot.vehiculo?.placa ? <p className="text-sm font-medium text-foreground">{ot.vehiculo.placa} · {ot.vehiculo.marca || 'Sin marca'} {ot.vehiculo.modelo || ''}</p> : null}
                          {ot.requerimientoCliente ? <p className="line-clamp-2 text-sm text-muted-foreground">{ot.requerimientoCliente}</p> : null}
                        </div>

                        <div className="flex items-center gap-2 lg:justify-end">
                          <Button onClick={() => router.push(ot.accesos?.detalle || `/dashboard/ots/${ot.id}`)}>
                            <Eye className="mr-2 h-4 w-4" />
                            Ver detalle
                          </Button>
                          <DropdownMenu>
                            <DropdownMenuTrigger asChild>
                              <Button variant="outline" size="icon" aria-label="Más acciones de la orden">
                                <MoreVertical className="h-4 w-4" />
                              </Button>
                            </DropdownMenuTrigger>
                            <DropdownMenuContent align="end">
                              <DropdownMenuItem onClick={() => router.push(ot.accesos?.cotizacion || `/dashboard/ots/${ot.id}/cotizacion`)}>
                                <Receipt className="h-4 w-4" />
                                Cotización
                              </DropdownMenuItem>
                              {flags.usaDanos ? (
                                <DropdownMenuItem onClick={() => router.push(ot.accesos?.danos || `/dashboard/ots/${ot.id}/danos`)}>
                                  <ShieldAlert className="h-4 w-4" />
                                  Daños
                                </DropdownMenuItem>
                              ) : null}
                            </DropdownMenuContent>
                          </DropdownMenu>
                        </div>
                      </CardContent>
                    </Card>
                  ))}
                </div>
              ) : (
                <DashboardEmptyState title="No hay OTs para esta consulta" description="La búsqueda encontró el cliente o vehículo, pero todavía no hay órdenes relacionadas registradas." icon={FileText} className="border-none bg-muted shadow-none" />
              )}
            </DashboardSection>
          </>
        )}
      </main>
    </div>
  );
}
