'use client';

import {
  DashboardEmptyState,
  DashboardListRow,
  DashboardPageIntro,
  DashboardSection,
  DashboardToolbar,
} from '@/components/dashboard-page';
import { PaginatedListFooter } from '@/components/paginated-list-footer';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { ErrorState } from '@/components/ui/error-state';
import { Field } from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import { SkeletonListRow } from '@/components/ui/skeleton';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { useFlagsConfiguracion } from '@/hooks/use-flags-configuracion';
import { useToast } from '@/hooks/use-toast';
import { clientesApi } from '@/lib/api';
import { createClientId } from '@/lib/client-id';
import { db } from '@/lib/db';
import { getLocalClientes, refreshClienteSearchCache, syncRemoteClientesCache } from '@/lib/offline-clientes';
import { syncEngine } from '@/lib/sync-engine';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { Mail, Pencil, Phone, Plus, Search, User, Users } from 'lucide-react';
import { useRouter } from 'next/navigation';
import { useRef, useState } from 'react';

const DEFAULT_PAGE_SIZE = 12;
const PAGE_SIZE_OPTIONS = [12, 24, 48, 96];

export default function ClientesPage() {
  const { usaHistorial } = useFlagsConfiguracion();
  const router = useRouter();
  const { toast } = useToast();
  const queryClient = useQueryClient();
  const lastRefreshKey = useRef('');
  const hasShownSyncError = useRef(false);

  const [search, setSearch] = useState('');
  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(DEFAULT_PAGE_SIZE);
  const [showForm, setShowForm] = useState(false);
  const [editingTarjeta, setEditingTarjeta] = useState<string | null>(null);
  const [formData, setFormData] = useState({
    nombre: '',
    nit: '',
    direccion: '',
    telefono: '',
    celular: '',
    email: '',
  });

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

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

        void (async () => {
          try {
            if (normalizedSearch.length >= 2) {
              await refreshClienteSearchCache(normalizedSearch);
            } else {
              await syncRemoteClientesCache();
            }

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

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

  const resetForm = () => {
    setShowForm(false);
    setEditingTarjeta(null);
    setFormData({ nombre: '', nit: '', direccion: '', telefono: '', celular: '', email: '' });
  };

  const createMutation = useMutation({
    mutationFn: async (payload: any) => {
      try {
        const created = await clientesApi.create(payload);

        await db.clientes.put({
          tarjeta: created.tarjeta,
          nombre: created.nombre,
          nit: created.nit,
          direccion: created.direccion,
          telefono: created.telefono,
          celular: created.celular,
          email: created.email,
          syncStatus: 'synced',
          lastModified: Date.now(),
        });

        return created;
      } catch (error: any) {
        const isOffline = !navigator.onLine;
        const isNetworkError = error instanceof TypeError || /Failed to fetch|NetworkError|ERR_EMPTY_RESPONSE/i.test(String(error?.message || ''));

        if (!isOffline && !isNetworkError) {
          throw error;
        }

        const localTarjeta = `PENDING-${Date.now()}`;
        const now = Date.now();

        await db.clientes.put({
          tarjeta: localTarjeta,
          nombre: payload.nombre,
          nit: payload.nit,
          direccion: payload.direccion,
          telefono: payload.telefono,
          celular: payload.celular,
          email: payload.email,
          syncStatus: 'pending',
          lastModified: now,
        });

        await syncEngine.queueEvent({
          eventId: createClientId('cliente-event'),
          eventType: 'CREATE_CLIENT',
          entityType: 'client',
          localId: localTarjeta,
          payload: { ...payload },
        });

        return {
          ...payload,
          tarjeta: localTarjeta,
          offlineQueued: true,
        };
      }
    },
    onSuccess: (result: any) => {
      queryClient.invalidateQueries({ queryKey: ['clientes'] });
      toast({
        variant: 'success',
        title: result?.offlineQueued ? 'Cliente guardado sin conexión' : 'Cliente creado',
        description: result?.offlineQueued ? 'Se guardó localmente y se sincronizará al volver la conexión.' : `Cliente ${result.nombre} creado`,
      });
      setPage(1);
      resetForm();
    },
    onError: (error: any) => {
      toast({ variant: 'destructive', title: 'Error', description: error.message || 'Error al crear cliente' });
    },
  });

  const updateMutation = useMutation({
    mutationFn: async ({ tarjeta, payload }: { tarjeta: string; payload: any }) => {
      try {
        const updated = await clientesApi.update(tarjeta, payload);
        await db.clientes.put({
          tarjeta: updated.tarjeta,
          nombre: updated.nombre,
          nit: updated.nit,
          direccion: updated.direccion,
          telefono: updated.telefono,
          celular: updated.celular,
          email: updated.email,
          syncStatus: 'synced',
          lastModified: Date.now(),
        });
        return updated;
      } catch (error: any) {
        const isOffline = !navigator.onLine;
        const isNetworkError = error instanceof TypeError || /Failed to fetch|NetworkError|ERR_EMPTY_RESPONSE/i.test(String(error?.message || ''));
        if (!isOffline && !isNetworkError) throw error;

        await db.clientes.update(tarjeta, { ...payload, syncStatus: 'pending', lastModified: Date.now() });
        await syncEngine.queueEvent({
          eventId: createClientId('cliente-event'),
          eventType: 'UPDATE_CLIENT',
          entityType: 'client',
          localId: tarjeta,
          payload: { tarjeta, ...payload },
        });

        return { ...payload, tarjeta, offlineQueued: true };
      }
    },
    onSuccess: (result: any) => {
      queryClient.invalidateQueries({ queryKey: ['clientes'] });
      toast({
        variant: 'success',
        title: result?.offlineQueued ? 'Guardado sin conexión' : 'Cliente actualizado',
        description: result?.offlineQueued ? 'Se sincronizará automáticamente.' : 'Cambios guardados.',
      });
      resetForm();
    },
    onError: (error: any) => toast({ variant: 'destructive', title: 'Error', description: error.message || 'Error al actualizar' }),
  });

  const handleSubmit = (event: React.FormEvent) => {
    event.preventDefault();

    const nombre = formData.nombre.trim();
    const nit = formData.nit.trim() || 'CF';
    const direccion = formData.direccion.trim();

    if (!nombre) {
      toast({ variant: 'destructive', title: 'Campo obligatorio', description: 'Hace falta el nombre.' });
      return;
    }

    if (!direccion) {
      toast({ variant: 'destructive', title: 'Campo obligatorio', description: 'Hace falta la dirección.' });
      return;
    }

    if (editingTarjeta) {
      updateMutation.mutate({ tarjeta: editingTarjeta, payload: { ...formData, nombre, nit, direccion } });
    } else {
      createMutation.mutate({ ...formData, nombre, nit, direccion });
    }
  };

  const clientes = data?.data || [];
  const total = data?.total || 0;
  const totalPages = data?.totalPages || 1;
  const currentPage = data?.page || page;
  const showingCount = clientes.length;
  const hasSearch = search.trim().length >= 2;

  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="Clientes"
          description="La vista separa búsqueda, resumen y listado. La caché local se lee primero y, si hay internet, se actualiza en segundo plano."
          icon={Users}
          tone="blue"
          badge={hasSearch ? 'Búsqueda activa' : 'Base de clientes'}
          onBack={() => router.push('/dashboard')}
          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 cliente'}
            </Button>
          }
          stats={[
            { label: 'Clientes totales', value: total, hint: 'Conteo general disponible', icon: Users },
            { label: 'En esta página', value: showingCount, hint: 'Resultados visibles ahora', icon: Search },
          ]}
          filters={
            <DashboardToolbar
              searchValue={search}
              onSearchChange={(value) => {
                setSearch(value);
                setPage(1);
              }}
              searchPlaceholder="Buscar por nombre, tarjeta, NIT o teléfono..."
            />
          }
        />

        {showForm ? (
          <DashboardSection title={editingTarjeta ? `Editar cliente ${editingTarjeta}` : 'Nuevo cliente'} description="Completa los datos esenciales para dejar al cliente listo para OTs y vehículos.">
            <form onSubmit={handleSubmit} className="space-y-4">
              <Field label="Nombre" htmlFor="cliente-nombre" required>
                <Input placeholder="Nombre completo del cliente" value={formData.nombre} onChange={(event) => setFormData({ ...formData, nombre: event.target.value })} className="h-12" />
              </Field>
              <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
                <Field label="NIT" htmlFor="cliente-nit" hint="Opcional. Si queda vacío se usa CF.">
                  <Input value={formData.nit} onChange={(event) => setFormData({ ...formData, nit: event.target.value })} className="h-12" />
                </Field>
                <Field label="Teléfono" htmlFor="cliente-telefono">
                  <Input type="tel" inputMode="tel" value={formData.telefono} onChange={(event) => setFormData({ ...formData, telefono: event.target.value })} className="h-12" />
                </Field>
              </div>
              <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
                <Field label="Celular" htmlFor="cliente-celular">
                  <Input type="tel" inputMode="tel" value={formData.celular} onChange={(event) => setFormData({ ...formData, celular: event.target.value })} className="h-12" />
                </Field>
                <Field label="Email" htmlFor="cliente-email">
                  <Input type="email" inputMode="email" value={formData.email} onChange={(event) => setFormData({ ...formData, email: event.target.value })} className="h-12" />
                </Field>
              </div>
              <Field label="Dirección" htmlFor="cliente-direccion" required>
                <Input value={formData.direccion} onChange={(event) => setFormData({ ...formData, direccion: event.target.value })} className="h-12" />
              </Field>
              <Button
                type="submit"
                className="h-12 w-full"
                disabled={createMutation.isPending || updateMutation.isPending}
              >
                {createMutation.isPending || updateMutation.isPending ? 'Guardando...' : editingTarjeta ? 'Guardar cambios' : 'Crear cliente'}
              </Button>
            </form>
          </DashboardSection>
        ) : null}

        {isLoading ? (
          <DashboardSection title="Listado" description="Cargando clientes disponibles.">
            <div className="divide-y divide-border">
              {Array.from({ length: 5 }).map((_, index) => (
                <SkeletonListRow key={index} />
              ))}
            </div>
          </DashboardSection>
        ) : isError ? (
          <DashboardSection title="Listado" description="No se pudo cargar el listado de clientes.">
            <ErrorState onRetry={() => refetch()} description="No se pudo cargar la lista de clientes guardada en este dispositivo." />
          </DashboardSection>
        ) : clientes.length === 0 ? (
          <DashboardEmptyState
            title={hasSearch ? 'No se encontraron clientes' : 'No hay clientes registrados'}
            description={hasSearch ? 'Prueba con otro nombre, tarjeta o número para ampliar la búsqueda.' : 'Crea el primer cliente para empezar a registrar vehículos y OTs correctamente.'}
            icon={Users}
            action={
              !hasSearch ? (
                <Button onClick={() => setShowForm(true)}>
                  <Plus className="mr-2 h-4 w-4" />
                  Crear el primero
                </Button>
              ) : undefined
            }
          />
        ) : (
          <DashboardSection title="Listado de clientes" description="Acceso rápido a historial y edición.">
            <div className="space-y-4">
              <PaginatedListFooter
                page={currentPage}
                limit={limit}
                total={total}
                totalPages={totalPages}
                itemLabel="clientes"
                onPageChange={setPage}
                onLimitChange={(nextLimit) => {
                  setLimit(nextLimit);
                  setPage(1);
                }}
                pageSizeOptions={PAGE_SIZE_OPTIONS}
              />

              {/* Mobile: filas táctiles de 64px. Desktop: tabla real, las columnas caben sin apretarse. */}
              <div className="overflow-hidden rounded-xl border border-border md:hidden">
                {clientes.map((cliente: any) => (
                  <DashboardListRow
                    key={cliente.tarjeta}
                    icon={<User className="h-4 w-4" />}
                    title={
                      <span className="flex min-w-0 items-center gap-2">
                        <span className="truncate">{cliente.nombre}</span>
                        {cliente.origen === 'local' ? <Badge variant="warning">Pendiente</Badge> : null}
                      </span>
                    }
                    meta={`${cliente.tarjeta} | NIT: ${cliente.nit || 'CF'}`}
                    onClick={usaHistorial ? () => router.push(`/dashboard/historial?cliente=${cliente.tarjeta}`) : undefined}
                    actions={
                      <Button
                        variant="ghost"
                        size="icon"
                        aria-label="Editar cliente"
                        onClick={() => {
                          setEditingTarjeta(cliente.tarjeta);
                          setShowForm(true);
                          setFormData({
                            nombre: cliente.nombre || '',
                            nit: cliente.nit || '',
                            direccion: cliente.direccion || '',
                            telefono: cliente.telefono || '',
                            celular: cliente.celular || '',
                            email: cliente.email || '',
                          });
                        }}
                      >
                        <Pencil className="h-4 w-4" />
                      </Button>
                    }
                  />
                ))}
              </div>

              <div className="hidden md:block">
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead>Cliente</TableHead>
                      <TableHead>Tarjeta / NIT</TableHead>
                      <TableHead>Contacto</TableHead>
                      <TableHead className="w-11" />
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {clientes.map((cliente: any) => (
                      <TableRow
                        key={cliente.tarjeta}
                        {...(usaHistorial
                          ? {
                              className: 'cursor-pointer',
                              role: 'link',
                              tabIndex: 0,
                              'aria-label': `Ver historial de ${cliente.nombre}`,
                              onClick: () => router.push(`/dashboard/historial?cliente=${cliente.tarjeta}`),
                              onKeyDown: (event: React.KeyboardEvent) => {
                                if (event.key === 'Enter' || event.key === ' ') {
                                  event.preventDefault();
                                  router.push(`/dashboard/historial?cliente=${cliente.tarjeta}`);
                                }
                              },
                            }
                          : {})}
                      >
                        <TableCell>
                          <span className="flex items-center gap-2 font-medium text-foreground">
                            {cliente.nombre}
                            {cliente.origen === 'local' ? <Badge variant="warning">Pendiente</Badge> : null}
                          </span>
                        </TableCell>
                        <TableCell className="text-muted-foreground">
                          {cliente.tarjeta} | {cliente.nit || 'CF'}
                        </TableCell>
                        <TableCell className="text-muted-foreground">
                          <div className="flex flex-wrap gap-3 text-xs">
                            {cliente.telefono ? <span className="flex items-center gap-1"><Phone size={12} /> {cliente.telefono}</span> : null}
                            {cliente.celular ? <span className="flex items-center gap-1"><Phone size={12} /> {cliente.celular}</span> : null}
                            {cliente.email ? <span className="flex items-center gap-1"><Mail size={12} /> {cliente.email}</span> : null}
                          </div>
                        </TableCell>
                        <TableCell onClick={(event) => event.stopPropagation()}>
                          <Button
                            variant="ghost"
                            size="icon"
                            aria-label="Editar cliente"
                            onClick={() => {
                              setEditingTarjeta(cliente.tarjeta);
                              setShowForm(true);
                              setFormData({
                                nombre: cliente.nombre || '',
                                nit: cliente.nit || '',
                                direccion: cliente.direccion || '',
                                telefono: cliente.telefono || '',
                                celular: cliente.celular || '',
                                email: cliente.email || '',
                              });
                            }}
                          >
                            <Pencil className="h-4 w-4" />
                          </Button>
                        </TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              </div>

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