import { useMemo, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { bsDesdeUsd, formatBs } from '@gustito/shared';
import { Icono } from '@gustito/shared/iconos';
import { supabase } from '../lib/supabase';

type Pedido = {
  id: string;
  total_usd: number;
  metodo_pago: string;
  tipo_entrega: string;
  recibido_en: string;
};

type FilaPago = {
  origen: string;
  fecha: string;
  descripcion: string;
  metodo: string;
  monto_usd: number;
  referencia: string | null;
  comprobante_url: string | null;
  estado: string;
};

function fechaHora(iso: string): string {
  const d = new Date(iso);
  return d.toLocaleString('es-VE', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit', hour12: true });
}

type Rendimiento = {
  mesero_id: string;
  nombre: string;
  mesas: number;
  pedidos: number;
  ventas_usd: number;
  propinas_usd: number;
};

const usd = (n: number) => `$${Number(n).toFixed(2)}`;
const claveDia = (d: Date) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;

const NOMBRE_METODO: Record<string, string> = {
  efectivo: 'Efectivo',
  pago_movil: 'Pago Móvil',
  transferencia: 'Transferencia',
  zelle: 'Zelle',
  punto_venta: 'Punto de venta',
};
const NOMBRE_ENTREGA: Record<string, string> = { delivery: 'Delivery', pickup: 'Mostrador', mesa: 'Mesa' };

export default function Estadisticas({
  restauranteId,
  marca,
  acento,
  tasaBs,
}: {
  restauranteId: string;
  marca: string;
  acento: string;
  tasaBs: number | null;
}) {
  const [dias, setDias] = useState<7 | 30>(30);
  const bsTxt = (n: number) => (tasaBs && tasaBs > 0 ? formatBs(bsDesdeUsd(n, tasaBs)) : null);

  const desde = useMemo(() => {
    const d = new Date();
    d.setHours(0, 0, 0, 0);
    d.setDate(d.getDate() - (dias - 1));
    return d;
  }, [dias]);

  const { data, isLoading } = useQuery({
    queryKey: ['estadisticas', restauranteId, dias],
    queryFn: async () => {
      const { data: peds } = await supabase
        .from('pedidos')
        .select('id,total_usd,metodo_pago,tipo_entrega,recibido_en')
        .eq('restaurante_id', restauranteId)
        .eq('estado', 'entregado')
        .gte('recibido_en', desde.toISOString())
        .order('recibido_en');
      const pedidos = (peds ?? []) as unknown as Pedido[];

      let items: { nombre: string; cantidad: number }[] = [];
      if (pedidos.length) {
        const ids = pedidos.map((p) => p.id);
        const { data: its } = await supabase.from('pedido_items').select('nombre,cantidad').in('pedido_id', ids);
        items = (its ?? []) as unknown as { nombre: string; cantidad: number }[];
      }
      return { pedidos, items };
    },
  });

  const { data: rend } = useQuery({
    queryKey: ['rendimiento-meseros', restauranteId, dias],
    queryFn: async () => {
      const { data, error } = await supabase.rpc('rendimiento_meseros', {
        p_restaurante_id: restauranteId,
        p_desde: desde.toISOString(),
      });
      if (error) throw error;
      return (data as unknown as Rendimiento[]) ?? [];
    },
  });

  // Detalle de pagos por método (pedido de Gilberto: poder cruzar cada pago
  // móvil/transferencia/zelle contra su referencia para verificarlo). Unifica
  // pagos de mostrador/delivery y de mesa vía la RPC reporte_pagos.
  const [metodoSel, setMetodoSel] = useState<string | null>(null);
  const detalleQ = useQuery({
    queryKey: ['reporte-pagos', restauranteId, dias, metodoSel],
    enabled: !!metodoSel,
    queryFn: async () => {
      const { data, error } = await supabase.rpc('reporte_pagos', {
        p_restaurante_id: restauranteId,
        p_desde: desde.toISOString(),
        p_metodo: metodoSel ?? undefined,
      });
      if (error) throw error;
      return (data as unknown as FilaPago[]) ?? [];
    },
  });
  const detalle = detalleQ.data ?? [];
  const totalDetalle = detalle.reduce((s, p) => s + Number(p.monto_usd), 0);


  async function verComprobante(path: string) {
    const { data, error } = await supabase.storage.from('comprobantes').createSignedUrl(path, 120);
    if (error) alert(error.message);
    else window.open(data.signedUrl, '_blank');
  }
  // Solo meseros con actividad en el período (los demás no ensucian la vista).
  const meseros = (rend ?? []).filter((m) => m.mesas > 0 || m.pedidos > 0 || Number(m.ventas_usd) > 0);
  const maxVentaMesero = Math.max(...meseros.map((m) => Number(m.ventas_usd)), 1);

  // useMemo: sin el, `?? []` fabrica arrays nuevos en cada render y los
  // useMemo de abajo (serie, top, por metodo) recalculan de gratis.
  const pedidos = useMemo(() => data?.pedidos ?? [], [data]);
  const items = useMemo(() => data?.items ?? [], [data]);

  const totalVentas = pedidos.reduce((s, p) => s + Number(p.total_usd), 0);
  const numPedidos = pedidos.length;
  const ticket = numPedidos ? totalVentas / numPedidos : 0;

  // Serie por día (llena los días sin ventas con 0).
  const serie = useMemo(() => {
    const mapa = new Map<string, { total: number; count: number }>();
    for (let i = 0; i < dias; i++) {
      const d = new Date(desde);
      d.setDate(desde.getDate() + i);
      mapa.set(claveDia(d), { total: 0, count: 0 });
    }
    for (const p of pedidos) {
      const k = claveDia(new Date(p.recibido_en));
      const e = mapa.get(k);
      if (e) {
        e.total += Number(p.total_usd);
        e.count += 1;
      }
    }
    return Array.from(mapa.entries()).map(([k, v]) => ({ k, ...v }));
  }, [pedidos, desde, dias]);

  const topProductos = useMemo(() => {
    const mapa = new Map<string, number>();
    for (const it of items) mapa.set(it.nombre, (mapa.get(it.nombre) ?? 0) + Number(it.cantidad));
    return Array.from(mapa.entries())
      .map(([nombre, cantidad]) => ({ nombre, cantidad }))
      .sort((a, b) => b.cantidad - a.cantidad)
      .slice(0, 6);
  }, [items]);

  const porMetodo = useMemo(() => agrupar(pedidos, 'metodo_pago', NOMBRE_METODO), [pedidos]);
  const porEntrega = useMemo(() => agrupar(pedidos, 'tipo_entrega', NOMBRE_ENTREGA), [pedidos]);

  return (
    <div className="space-y-5">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <h1 className="text-xl font-extrabold">Estadísticas</h1>
        <div className="flex rounded-xl bg-superficie p-1 ring-1 ring-white/10">
          {([7, 30] as const).map((n) => (
            <button
              key={n}
              onClick={() => setDias(n)}
              className="rounded-lg px-3 py-1.5 text-xs font-bold transition"
              style={dias === n ? { background: marca, color: contrasteTxt(marca) } : { color: 'rgba(255,255,255,.6)' }}
            >
              {n} días
            </button>
          ))}
        </div>
      </div>

      <div className="grid grid-cols-3 gap-2 sm:gap-3">
        <ResumenE label="Ventas entregadas" valor={usd(totalVentas)} bs={bsTxt(totalVentas)} color="#22C55E" />
        <ResumenE label="Pedidos" valor={String(numPedidos)} color={acento} />
        <ResumenE label="Ticket promedio" valor={usd(ticket)} bs={bsTxt(ticket)} color="#FFFFFF" />
      </div>

      <section className="rounded-2xl bg-superficie p-4 ring-1 ring-white/10">
        <h2 className="mb-3 text-sm font-extrabold uppercase tracking-wide text-niebla">Ventas por día</h2>
        {isLoading ? (
          <p className="py-10 text-center text-sm text-niebla">Cargando…</p>
        ) : totalVentas === 0 ? (
          <p className="py-10 text-center text-sm text-niebla">Aún no hay ventas entregadas en este período.</p>
        ) : (
          <GraficoBarras serie={serie} color={acento} />
        )}
      </section>

      <div className="grid gap-4 md:grid-cols-2">
        <section className="rounded-2xl bg-superficie p-4 ring-1 ring-white/10">
          <h2 className="mb-3 text-sm font-extrabold uppercase tracking-wide text-niebla">Más vendidos</h2>
          {topProductos.length === 0 ? (
            <p className="py-6 text-center text-sm text-niebla">Sin datos todavía.</p>
          ) : (
            <div className="space-y-2.5">
              {topProductos.map((p) => (
                <BarraH key={p.nombre} label={p.nombre} valor={p.cantidad} max={topProductos[0].cantidad} sufijo="u" color={acento} />
              ))}
            </div>
          )}
        </section>

        <div className="space-y-4">
          <section className="rounded-2xl bg-superficie p-4 ring-1 ring-white/10">
            <h2 className="mb-1 text-sm font-extrabold uppercase tracking-wide text-niebla">Métodos de pago</h2>
            <p className="mb-3 text-[11px] text-niebla">Toca un método para ver cada pago y su referencia.</p>
            {porMetodo.length === 0 ? (
              <p className="py-6 text-center text-sm text-niebla">Sin datos.</p>
            ) : (
              <div className="space-y-2.5">
                {porMetodo.map((m) => (
                  <button
                    key={m.clave}
                    onClick={() => setMetodoSel(metodoSel === m.clave ? null : m.clave)}
                    className="block w-full rounded-lg text-left ring-offset-2 ring-offset-superficie transition"
                    style={metodoSel === m.clave ? { boxShadow: `0 0 0 2px ${acento}` } : undefined}
                  >
                    <BarraH label={m.label} valor={m.count} max={porMetodo[0].count} sufijo="" color="#22C55E" nota={usd(m.total)} />
                  </button>
                ))}
              </div>
            )}
          </section>

          <section className="rounded-2xl bg-superficie p-4 ring-1 ring-white/10">
            <h2 className="mb-3 text-sm font-extrabold uppercase tracking-wide text-niebla">Tipo de entrega</h2>
            {porEntrega.length === 0 ? (
              <p className="py-6 text-center text-sm text-niebla">Sin datos.</p>
            ) : (
              <div className="space-y-2.5">
                {porEntrega.map((m) => (
                  <BarraH key={m.clave} label={m.label} valor={m.count} max={porEntrega[0].count} sufijo="" color="#F59E0B" nota={usd(m.total)} />
                ))}
              </div>
            )}
          </section>
        </div>
      </div>

      {metodoSel && (
        <section className="rounded-2xl bg-superficie p-4 ring-1 ring-white/10">
          <div className="mb-3 flex items-center justify-between gap-2">
            <div>
              <h2 className="text-sm font-extrabold uppercase tracking-wide text-niebla">
                Detalle · {NOMBRE_METODO[metodoSel] ?? metodoSel}
              </h2>
              <p className="text-[11px] text-niebla">Últimos {dias} días · mostrador, delivery y mesa juntos</p>
            </div>
            <button
              onClick={() => setMetodoSel(null)}
              className="grid h-8 w-8 shrink-0 place-items-center rounded-full bg-white/10 text-white/70 hover:text-white"
              aria-label="Cerrar detalle"
            >
              <Icono nombre="cerrar" className="h-4 w-4" />
            </button>
          </div>

          {detalleQ.isLoading ? (
            <p className="py-6 text-center text-sm text-niebla">Cargando…</p>
          ) : detalle.length === 0 ? (
            <p className="py-6 text-center text-sm text-niebla">Sin pagos con este método en el período.</p>
          ) : (
            <>
              <div className="space-y-2">
                {detalle.map((p, i) => (
                  <div
                    key={i}
                    className="flex items-center justify-between gap-3 rounded-xl bg-superficie-2 px-3 py-2.5 text-sm ring-1 ring-white/10"
                  >
                    <div className="min-w-0">
                      <p className="truncate font-bold text-white">{p.descripcion}</p>
                      <p className="text-xs text-niebla">
                        {fechaHora(p.fecha)} · {p.referencia ? `Ref ${p.referencia}` : 'Sin referencia'}
                      </p>
                    </div>
                    <div className="shrink-0 text-right">
                      <p className="font-black tabular-nums" style={{ color: acento }}>
                        {usd(p.monto_usd)}
                      </p>
                      {p.comprobante_url && (
                        <button
                          onClick={() => verComprobante(p.comprobante_url!)}
                          className="text-xs font-bold text-dorado underline"
                        >
                          Ver comprobante
                        </button>
                      )}
                    </div>
                  </div>
                ))}
              </div>
              <p className="mt-3 text-right text-sm font-bold text-white/80">
                {detalle.length} pago{detalle.length === 1 ? '' : 's'} · Total {usd(totalDetalle)}
              </p>
            </>
          )}
        </section>
      )}

      {meseros.length > 0 && (
        <section className="rounded-2xl bg-superficie p-4 ring-1 ring-white/10">
          <h2 className="mb-1 text-sm font-extrabold uppercase tracking-wide text-niebla">Rendimiento de meseros</h2>
          <p className="mb-3 text-[11px] text-niebla">Por el mesero asignado a la mesa, en los últimos {dias} días.</p>
          <div className="space-y-3">
            {meseros.map((m) => {
              const venta = Number(m.ventas_usd);
              const propina = Number(m.propinas_usd);
              return (
                <div key={m.mesero_id}>
                  <div className="mb-1 flex items-baseline justify-between gap-2 text-sm">
                    <span className="truncate font-bold">{m.nombre}</span>
                    <span className="shrink-0 font-black tabular-nums text-emerald-400">{usd(venta)}</span>
                  </div>
                  <div className="h-2 overflow-hidden rounded-full bg-white/5">
                    <div
                      className="h-full rounded-full bg-emerald-500"
                      style={{ width: `${Math.max(4, Math.round((venta / maxVentaMesero) * 100))}%` }}
                    />
                  </div>
                  <div className="mt-1 flex flex-wrap gap-x-3 gap-y-0.5 text-[11px] text-niebla">
                    <span>{m.mesas} mesa{m.mesas === 1 ? '' : 's'}</span>
                    <span>{m.pedidos} pedido{m.pedidos === 1 ? '' : 's'}</span>
                    {propina > 0 && <span className="font-bold text-amber-300">Propinas {usd(propina)}</span>}
                    {bsTxt(venta) && <span>{bsTxt(venta)}</span>}
                  </div>
                </div>
              );
            })}
          </div>
        </section>
      )}
    </div>
  );
}

function agrupar(pedidos: Pedido[], campo: 'metodo_pago' | 'tipo_entrega', nombres: Record<string, string>) {
  const mapa = new Map<string, { count: number; total: number }>();
  for (const p of pedidos) {
    const k = p[campo];
    const e = mapa.get(k) ?? { count: 0, total: 0 };
    e.count += 1;
    e.total += Number(p.total_usd);
    mapa.set(k, e);
  }
  return Array.from(mapa.entries())
    .map(([clave, v]) => ({ clave, label: nombres[clave] ?? clave, ...v }))
    .sort((a, b) => b.count - a.count);
}

function GraficoBarras({ serie, color }: { serie: { k: string; total: number; count: number }[]; color: string }) {
  const max = Math.max(...serie.map((s) => s.total), 1);
  const n = serie.length;
  const paso = n > 14 ? 7 : n > 7 ? 2 : 1; // cada cuántas barras poner etiqueta

  return (
    <div>
      {/* Contenedor de altura fija: las barras se anclan al fondo con position absolute,
          así el porcentaje se calcula contra los 160px (h-40) y no colapsa. */}
      <div className="flex h-40 items-stretch gap-1">
        {serie.map((s) => {
          const h = Math.max(2, Math.round((s.total / max) * 100));
          const [, mm, dd] = s.k.split('-');
          return (
            <div key={s.k} className="group relative flex-1">
              <div className="pointer-events-none absolute bottom-full left-1/2 z-10 mb-1 hidden -translate-x-1/2 whitespace-nowrap rounded-lg bg-black/90 px-2 py-1 text-[11px] font-semibold text-white ring-1 ring-white/10 group-hover:block">
                {dd}/{mm}: {usd(s.total)} · {s.count} ped.
              </div>
              <div
                className="absolute inset-x-0 bottom-0 rounded-t transition-[height]"
                style={{ height: `${h}%`, background: color, opacity: s.total ? 1 : 0.25 }}
              />
            </div>
          );
        })}
      </div>
      <div className="mt-1 flex gap-1">
        {serie.map((s, i) => {
          const [, mm, dd] = s.k.split('-');
          return (
            <span key={s.k} className="flex-1 text-center text-[9px] font-semibold text-white/40">
              {i % paso === 0 ? `${dd}/${mm}` : ''}
            </span>
          );
        })}
      </div>
    </div>
  );
}

function BarraH({
  label,
  valor,
  max,
  sufijo,
  color,
  nota,
}: {
  label: string;
  valor: number;
  max: number;
  sufijo: string;
  color: string;
  nota?: string;
}) {
  const pct = Math.max(4, Math.round((valor / Math.max(max, 1)) * 100));
  return (
    <div>
      <div className="mb-1 flex items-baseline justify-between gap-2 text-sm">
        <span className="truncate font-semibold">{label}</span>
        <span className="shrink-0 font-bold tabular-nums" style={{ color }}>
          {valor}
          {sufijo}
          {nota ? <span className="ml-1 text-xs font-normal text-niebla">· {nota}</span> : null}
        </span>
      </div>
      <div className="h-2 overflow-hidden rounded-full bg-white/5">
        <div className="h-full rounded-full" style={{ width: `${pct}%`, background: color }} />
      </div>
    </div>
  );
}

function ResumenE({ label, valor, bs, color }: { label: string; valor: string; bs?: string | null; color: string }) {
  return (
    <div className="rounded-2xl bg-superficie p-3 text-center ring-1 ring-white/10 sm:p-4">
      <p className="text-xs font-semibold uppercase tracking-wide text-niebla">{label}</p>
      <p className="mt-1 text-lg font-black tabular-nums sm:text-2xl" style={{ color }}>
        {valor}
      </p>
      {bs && <p className="mt-0.5 text-[11px] font-semibold tabular-nums text-niebla">{bs}</p>}
    </div>
  );
}

// Blanco o negro segun contraste con el color de marca (bordes de botones activos).
function contrasteTxt(hex: string): string {
  const c = hex.replace('#', '');
  if (c.length < 6) return '#0D0F1E';
  const [r, g, b] = [0, 2, 4].map((i) => parseInt(c.slice(i, i + 2), 16) / 255);
  const f = (v: number) => (v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4));
  const lum = 0.2126 * f(r) + 0.7152 * f(g) + 0.0722 * f(b);
  return (1.05) / (lum + 0.05) >= (lum + 0.05) / 0.07 ? '#FFFFFF' : '#0D0F1E';
}
