'use client';

import { useAuth } from '@/components/providers';
import { DashboardEmptyState, DashboardPageIntro, DashboardSection } from '@/components/dashboard-page';
import { Button } from '@/components/ui/button';
import { Skeleton, SkeletonStatCard } from '@/components/ui/skeleton';
import { reportesApi, type ResumenReportes } from '@/lib/api';
import { db } from '@/lib/db';
import { formatCurrency, formatDate, getEstadoLabel } from '@/lib/utils';
import { useQuery } from '@tanstack/react-query';
import { BarChart3, Car, Download, FileText, Receipt, TrendingUp, Users, WifiOff, Wrench } from 'lucide-react';
import { useRouter } from 'next/navigation';

type ResumenConOrigen = ResumenReportes & { origen: 'servidor' | 'local' };

function toCSV(rows: ResumenReportes['recientes']): string {
  const headers = ['numero_ot', 'cliente', 'cliente_tarjeta', 'placa', 'estado', 'fecha_entrada', 'total_cotizacion'];
  const body = rows.map((row) => [
    row.numeroOt || '',
    row.clienteNombre || '',
    row.clienteTarjeta || '',
    row.placa || '',
    getEstadoLabel(row.estado),
    row.fechaEntrada ? formatDate(row.fechaEntrada) : '',
    row.total || 0,
  ]);

  return [headers, ...body]
    .map((line) => line.map((value) => `"${String(value).replace(/"/g, '""')}"`).join(','))
    .join('\n');
}

// Respaldo para cuando no hay conexión: la app es offline-first y una tablet
// en el taller puede quedarse sin señal. Calcula lo que se pueda con lo que
// haya en el equipo — los montos salen incompletos porque el cache guarda
// las OTs pero no siempre su cotización, y por eso la pantalla avisa cuando
// las cifras vienen de acá y no del servidor.
async function calcularDesdeEsteEquipo(): Promise<ResumenConOrigen> {
  const ots = await db.ordenesTrabajo.toArray();

  const porEstado = ots.reduce<Record<string, number>>((acc, item) => {
    acc[item.estado] = (acc[item.estado] || 0) + 1;
    return acc;
  }, {});

  const totalCotizado = ots.reduce((sum, item) => sum + Number(item?.cotizacion?.total || 0), 0);
  const totalCotizadoAprobado = ots.reduce(
    (sum, item) => sum + (item?.cotizacion?.estado === 'aprobada' ? Number(item?.cotizacion?.total || 0) : 0),
    0,
  );
  const otsConCotizacion = ots.filter((item) => Number(item?.cotizacion?.total || 0) > 0);

  const topClientes = Object.values(
    ots.reduce<Record<string, ResumenReportes['topClientes'][number]>>((acc, item) => {
      if (!item.clienteTarjeta) return acc;
      const current = acc[item.clienteTarjeta] || {
        tarjeta: item.clienteTarjeta,
        nombre: null,
        recepciones: 0,
        totalCotizado: 0,
      };
      current.recepciones += 1;
      current.totalCotizado += Number(item?.cotizacion?.total || 0);
      acc[item.clienteTarjeta] = current;
      return acc;
    }, {}),
  )
    .sort((a, b) => b.recepciones - a.recepciones || b.totalCotizado - a.totalCotizado)
    .slice(0, 5);

  const topVehiculos = Object.values(
    ots.reduce<Record<string, ResumenReportes['topVehiculos'][number]>>((acc, item) => {
      const placa = String(item?.vehiculo?.placa || '').trim();
      if (!placa) return acc;
      const current = acc[placa] || {
        placa,
        marca: item?.vehiculo?.marca || null,
        modelo: item?.vehiculo?.modelo || null,
        visitas: 0,
      };
      current.visitas += 1;
      acc[placa] = current;
      return acc;
    }, {}),
  )
    .sort((a, b) => b.visitas - a.visitas)
    .slice(0, 5);

  const recientes = ots
    .slice()
    .sort((a, b) => new Date(b.fechaEntrada).getTime() - new Date(a.fechaEntrada).getTime())
    .slice(0, 20)
    .map((ot) => ({
      numeroOt: ot.numeroOt || null,
      estado: ot.estado,
      fechaEntrada: ot.fechaEntrada ? new Date(ot.fechaEntrada).toISOString() : null,
      placa: ot?.vehiculo?.placa || null,
      clienteTarjeta: ot.clienteTarjeta || null,
      clienteNombre: null,
      total: Number(ot?.cotizacion?.total || 0),
    }));

  return {
    origen: 'local',
    totalOts: ots.length,
    totalClientes: new Set(ots.map((ot) => ot?.clienteTarjeta).filter(Boolean)).size,
    totalVehiculos: new Set(ots.map((ot) => ot?.vehiculo?.placa).filter(Boolean)).size,
    totalCotizado,
    totalCotizadoAprobado,
    ticketPromedio: otsConCotizacion.length > 0 ? totalCotizado / otsConCotizacion.length : 0,
    cotizacionesPendientes: ots.filter((item) => item?.cotizacion && item.cotizacion.estado !== 'aprobada').length,
    porEstado,
    topClientes,
    topVehiculos,
    recientes,
  };
}

export default function ReportesPage() {
  const router = useRouter();
  const { canRead } = useAuth();

  const { data, isLoading } = useQuery<ResumenConOrigen>({
    queryKey: ['reportes', 'resumen'],
    queryFn: async () => {
      try {
        const resumen = await reportesApi.resumen();
        return { ...resumen, origen: 'servidor' as const };
      } catch {
        return calcularDesdeEsteEquipo();
      }
    },
    refetchOnWindowFocus: true,
  });

  if (!canRead('reportes')) {
    return (
      <div className="min-h-full">
        <main className="mx-auto max-w-4xl p-6">
          <DashboardEmptyState
            title="Sin acceso"
            description="No tienes permisos para consultar reportes."
            icon={BarChart3}
          />
        </main>
      </div>
    );
  }

  const exportCSV = () => {
    const csv = toCSV(data?.recientes || []);
    const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = `reporte_ots_${new Date().toISOString().slice(0, 10)}.csv`;
    link.click();
    URL.revokeObjectURL(url);
  };

  const estados = Object.entries(data?.porEstado || {});

  return (
    <div className="min-h-full pb-16 md:pb-10">
      <main className="mx-auto flex max-w-7xl flex-col gap-6">
        <DashboardPageIntro
          title="Reportes"
          description="Resumen del taller: carga de trabajo, cotizaciones y qué clientes y vehículos regresan más."
          icon={BarChart3}
          tone="rose"
          badge="Reportes"
          onBack={() => router.push('/dashboard')}
          actions={
            <Button onClick={exportCSV} disabled={!data?.recientes?.length}>
              <Download className="mr-2 h-4 w-4" />
              Exportar CSV
            </Button>
          }
          stats={
            isLoading
              ? undefined
              : [
                  { label: 'Recepciones', value: data?.totalOts || 0, hint: 'Total registrado', icon: FileText },
                  { label: 'Clientes', value: data?.totalClientes || 0, hint: 'Con al menos una recepción', icon: Users },
                  { label: 'Vehículos', value: data?.totalVehiculos || 0, hint: 'Únicos por placa', icon: Car },
                  { label: 'Total cotizado', value: formatCurrency(data?.totalCotizado || 0), hint: 'Acumulado general', icon: TrendingUp },
                ]
          }
        />

        {isLoading ? (
          <div className="flex flex-col gap-6">
            <div className="grid grid-cols-2 gap-3 lg:grid-cols-4">
              {Array.from({ length: 4 }).map((_, index) => (
                <SkeletonStatCard key={index} />
              ))}
            </div>
            <DashboardSection title="Resumen" description="Cargando la información del taller.">
              <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3">
                {Array.from({ length: 3 }).map((_, index) => (
                  <div key={index} className="space-y-2 rounded-xl border border-border bg-muted p-4">
                    <Skeleton className="h-3 w-2/3" />
                    <Skeleton className="h-6 w-1/3" />
                  </div>
                ))}
              </div>
            </DashboardSection>
          </div>
        ) : (
          <>
            {data?.origen === 'local' ? (
              <div className="flex items-start gap-3 rounded-xl border border-warning/30 bg-warning-soft px-5 py-4 text-sm font-medium text-warning">
                <WifiOff className="mt-0.5 h-4 w-4 shrink-0" />
                <span>
                  No se pudo conectar al servidor, así que estas cifras se calcularon con lo que hay guardado en este
                  equipo y pueden estar incompletas. Cuando vuelva la conexión, actualiza la pantalla para ver los
                  montos reales.
                </span>
              </div>
            ) : null}

            <div className="grid gap-6 xl:grid-cols-[1.2fr_0.8fr]">
              <DashboardSection title="Qué incluye este resumen" description="Cada bloque de abajo responde una de estas preguntas.">
                <div className="grid gap-3 md:grid-cols-2">
                  {[
                    { title: 'Recepciones por estado', desc: 'Cuánto trabajo hay en cada etapa del taller.', icon: Wrench },
                    { title: 'Cotizaciones', desc: 'Cuánto está pendiente de aprobar y cuánto ya se aprobó.', icon: Receipt },
                    { title: 'Clientes frecuentes', desc: 'Quién regresa más y cuánto representa en dinero.', icon: Users },
                    { title: 'Vehículos recurrentes', desc: 'Qué unidades vuelven con más frecuencia.', icon: Car },
                  ].map((item) => (
                    <div key={item.title} className="rounded-xl border border-border bg-surface p-4 shadow-sm">
                      <div className="flex h-10 w-10 items-center justify-center rounded-xl bg-muted text-foreground">
                        <item.icon className="h-5 w-5" />
                      </div>
                      <h3 className="mt-4 text-base font-bold text-foreground">{item.title}</h3>
                      <p className="mt-1 text-sm text-muted-foreground">{item.desc}</p>
                    </div>
                  ))}
                </div>
              </DashboardSection>

              <DashboardSection title="Cotizaciones" description="Cómo viene la parte comercial del taller.">
                <div className="space-y-3">
                  <div className="rounded-xl border border-border bg-muted p-4"><p className="text-sm text-muted-foreground">Pendientes de aprobar</p><p className="mt-2 text-3xl font-bold text-foreground">{data?.cotizacionesPendientes || 0}</p></div>
                  <div className="rounded-xl border border-border bg-muted p-4"><p className="text-sm text-muted-foreground">Monto aprobado</p><p className="mt-2 text-3xl font-bold text-success">{formatCurrency(data?.totalCotizadoAprobado || 0)}</p></div>
                  <div className="rounded-xl border border-border bg-muted p-4"><p className="text-sm text-muted-foreground">Promedio por cotización</p><p className="mt-2 text-3xl font-bold text-foreground">{formatCurrency(data?.ticketPromedio || 0)}</p></div>
                </div>
              </DashboardSection>
            </div>

            <DashboardSection title="Recepciones por estado" description="En qué etapa está cada vehículo que entró al taller.">
              {estados.length > 0 ? (
                <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3">
                  {estados.map(([estado, count]) => (
                    <div key={estado} className="rounded-xl border border-border bg-muted p-4">
                      <p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">{getEstadoLabel(estado)}</p>
                      <p className="mt-2 text-2xl font-bold text-foreground">{count as number}</p>
                    </div>
                  ))}
                </div>
              ) : (
                <DashboardEmptyState
                  title="Todavía no hay recepciones"
                  description="Cuando reciban el primer vehículo, acá se va a ver cuántos hay en cada etapa."
                  icon={Wrench}
                  className="border-none bg-muted shadow-none"
                />
              )}
            </DashboardSection>

            <div className="grid gap-6 xl:grid-cols-2">
              <DashboardSection title="Clientes frecuentes" description="Los que más veces han dejado un vehículo en el taller.">
                {data?.topClientes?.length ? (
                  <div className="space-y-3">
                    {data.topClientes.map((cliente) => (
                      <div key={cliente.tarjeta} className="flex items-center justify-between gap-3 rounded-xl border border-border bg-surface p-4 shadow-sm">
                        <div className="min-w-0">
                          <p className="truncate font-bold text-foreground">{cliente.nombre || cliente.tarjeta}</p>
                          <p className="mt-1 text-sm text-muted-foreground">{cliente.recepciones} recepción(es)</p>
                        </div>
                        <p className="shrink-0 text-sm font-semibold text-foreground">{formatCurrency(cliente.totalCotizado)}</p>
                      </div>
                    ))}
                  </div>
                ) : (
                  <DashboardEmptyState title="Sin datos todavía" description="Cuando un cliente regrese por segunda vez, va a aparecer acá." icon={Users} className="border-none bg-muted shadow-none" />
                )}
              </DashboardSection>

              <DashboardSection title="Vehículos recurrentes" description="Las placas que más visitas tienen registradas.">
                {data?.topVehiculos?.length ? (
                  <div className="space-y-3">
                    {data.topVehiculos.map((vehiculo) => (
                      <div key={vehiculo.placa} className="flex items-center justify-between gap-3 rounded-xl border border-border bg-surface p-4 shadow-sm">
                        <div className="min-w-0">
                          <p className="truncate font-bold text-foreground">{vehiculo.placa}</p>
                          <p className="mt-1 truncate text-sm text-muted-foreground">
                            {[vehiculo.marca, vehiculo.modelo].filter(Boolean).join(' ') || 'Sin marca ni modelo registrados'}
                          </p>
                        </div>
                        <p className="shrink-0 text-sm font-semibold text-foreground">{vehiculo.visitas} visita(s)</p>
                      </div>
                    ))}
                  </div>
                ) : (
                  <DashboardEmptyState title="Sin datos todavía" description="Cuando un vehículo vuelva por segunda vez, va a aparecer acá." icon={Car} className="border-none bg-muted shadow-none" />
                )}
              </DashboardSection>
            </div>

            <DashboardSection title="Últimas recepciones" description="Las 20 más recientes. Se pueden descargar con el botón Exportar CSV.">
              {data?.recientes?.length ? (
                <div className="space-y-3">
                  {data.recientes.map((ot, index) => (
                    <div key={`${ot.numeroOt || ot.placa || 'ot'}-${index}`} className="flex items-center justify-between gap-3 rounded-xl border border-border bg-surface p-4">
                      <div className="min-w-0">
                        <p className="truncate font-bold text-foreground">{ot.numeroOt || 'Sin número asignado'}</p>
                        <p className="mt-1 truncate text-sm text-muted-foreground">
                          {[ot.placa, ot.clienteNombre || ot.clienteTarjeta, ot.fechaEntrada ? formatDate(ot.fechaEntrada) : null]
                            .filter(Boolean)
                            .join(' · ')}
                        </p>
                      </div>
                      <div className="shrink-0 text-right">
                        <span className="rounded-full bg-muted px-3 py-1 text-xs font-semibold text-muted-foreground">{getEstadoLabel(ot.estado)}</span>
                        <p className="mt-2 text-sm font-semibold text-foreground">{formatCurrency(ot.total)}</p>
                      </div>
                    </div>
                  ))}
                </div>
              ) : (
                <DashboardEmptyState
                  title="Todavía no hay recepciones"
                  description="Cuando registren la primera recepción, va a aparecer acá y se podrá exportar."
                  icon={FileText}
                  className="border-none bg-muted shadow-none"
                />
              )}
            </DashboardSection>
          </>
        )}
      </main>
    </div>
  );
}
