import { Icono } from '@gustito/shared/iconos';
import { useMemo, useState } from 'react';
import { precioDual, formatUsd, type OpcionGrupo, type Producto } from '@gustito/shared';
import { useCerrarConAtras } from '../lib/useCerrarConAtras';

export interface ItemElegido {
  producto_id: string;
  nombre: string;
  precio_usd: number;
  opcionesElegidas: string[];
  /**
   * Lo mismo que opcionesElegidas pero diciendo de que grupo salio cada una.
   * Hace falta porque el precio depende del grupo: "Pernil" es gratis en
   * "Elige tu proteina (incluida)" y cuesta 1,50 en "Otra proteina?".
   */
  opcionesSel: { g: string; o: string }[];
  opcionesTexto: string;
  cantidad?: number;
}

export default function OpcionesModal({
  producto,
  tasa,
  onAgregar,
  onCerrar,
}: {
  producto: Producto;
  tasa: number | null;
  onAgregar: (items: ItemElegido[]) => void;
  onCerrar: () => void;
}) {
  useCerrarConAtras(onCerrar);
  const grupos = producto.opciones ?? [];
  if (grupos.length === 0) {
    return <ModalSimple producto={producto} tasa={tasa} onAgregar={onAgregar} onCerrar={onCerrar} />;
  }
  const grupoCantidad = grupos.find((g) => g.tipo === 'cantidad');
  if (grupoCantidad) {
    return <ModalCantidad producto={producto} grupo={grupoCantidad} tasa={tasa} onAgregar={onAgregar} onCerrar={onCerrar} />;
  }
  return <ModalMarcar producto={producto} grupos={grupos} tasa={tasa} onAgregar={onAgregar} onCerrar={onCerrar} />;
}

// ── Producto simple (sin opciones): elegir cuantas, igual que las empanadas ──
function ModalSimple({
  producto,
  tasa,
  onAgregar,
  onCerrar,
}: {
  producto: Producto;
  tasa: number | null;
  onAgregar: (items: ItemElegido[]) => void;
  onCerrar: () => void;
}) {
  const [cant, setCant] = useState(1);
  const total = producto.precio_usd * cant;

  function confirmar() {
    onAgregar([
      {
        producto_id: producto.id,
        nombre: producto.nombre,
        precio_usd: producto.precio_usd,
        cantidad: cant,
        opcionesElegidas: [],
        opcionesSel: [],
        opcionesTexto: '',
      },
    ]);
    onCerrar();
  }

  return (
    <Marco
      titulo={producto.nombre}
      sub={`${formatUsd(producto.precio_usd)} c/u`}
      onCerrar={onCerrar}
      footer={
        <button
          onClick={confirmar}
          className="flex w-full items-center justify-between rounded-2xl bg-marca px-5 py-3.5 font-bold text-marca-contraste shadow-flotante active:scale-[0.99]"
        >
          <span>Agregar {cant}</span>
          <span>{precioDual(total, tasa)}</span>
        </button>
      }
    >
      <div className="flex items-center justify-between rounded-xl border-2 border-stone-200 px-4 py-3">
        <span className="text-sm font-bold text-stone-700">¿Cuántas quieres?</span>
        <div className="flex items-center gap-3">
          <button
            onClick={() => setCant((c) => Math.max(1, c - 1))}
            disabled={cant <= 1}
            className="grid h-9 w-9 place-items-center rounded-full bg-stone-100 text-xl text-stone-600 disabled:opacity-40"
          >
            −
          </button>
          <span className="w-6 text-center text-lg font-extrabold">{cant}</span>
          <button
            onClick={() => setCant((c) => c + 1)}
            className="grid h-9 w-9 place-items-center rounded-full bg-marca text-xl text-marca-contraste"
          >
            +
          </button>
        </div>
      </div>
    </Marco>
  );
}

function Marco({ titulo, sub, onCerrar, children, footer }: { titulo: string; sub: string; onCerrar: () => void; children: React.ReactNode; footer: React.ReactNode }) {
  return (
    <div className="fixed inset-0 z-30 flex items-end justify-center bg-black/40 sm:items-center" onClick={onCerrar}>
      <div className="max-h-[92vh] w-full max-w-lg overflow-y-auto rounded-t-3xl bg-white sm:rounded-3xl" onClick={(e) => e.stopPropagation()}>
        <div className="sticky top-0 z-10 flex items-center justify-between border-b border-stone-100 bg-white p-4">
          <div className="min-w-0">
            <h2 className="truncate text-lg font-extrabold text-stone-800">{titulo}</h2>
            <p className="text-xs text-stone-500">{sub}</p>
          </div>
          <button onClick={onCerrar} className="h-8 w-8 shrink-0 text-2xl leading-none text-stone-400">&times;</button>
        </div>
        <div className="p-4">{children}</div>
        <div className="sticky bottom-0 border-t border-stone-100 bg-white p-4 pb-[calc(1rem+env(safe-area-inset-bottom))]">{footer}</div>
      </div>
    </div>
  );
}

// ── Modo cantidad por opcion (ej. empanadas: 3 de queso, 2 de pollo) ──
function ModalCantidad({
  producto,
  grupo,
  tasa,
  onAgregar,
  onCerrar,
}: {
  producto: Producto;
  grupo: OpcionGrupo;
  tasa: number | null;
  onAgregar: (items: ItemElegido[]) => void;
  onCerrar: () => void;
}) {
  const [cant, setCant] = useState<Record<string, number>>({});
  const [err, setErr] = useState<string | null>(null);

  function set(nombre: string, delta: number) {
    setErr(null);
    setCant((p) => ({ ...p, [nombre]: Math.max(0, (p[nombre] ?? 0) + delta) }));
  }

  const { total, unidades } = useMemo(() => {
    let total = 0;
    let unidades = 0;
    for (const o of grupo.opciones) {
      const q = cant[o.nombre] ?? 0;
      total += (producto.precio_usd + o.precio_extra) * q;
      unidades += q;
    }
    return { total, unidades };
  }, [cant, grupo.opciones, producto.precio_usd]);

  // Precio real por unidad = base + extra de la opcion (el "desde" usa la mas barata).
  const minUnit = producto.precio_usd + Math.min(...grupo.opciones.map((o) => o.precio_extra));

  function confirmar() {
    if (grupo.obligatorio && unidades === 0) {
      setErr('Elige al menos una.');
      return;
    }
    const items: ItemElegido[] = grupo.opciones
      .filter((o) => (cant[o.nombre] ?? 0) > 0)
      .map((o) => ({
        producto_id: producto.id,
        nombre: producto.nombre,
        precio_usd: producto.precio_usd + o.precio_extra,
        cantidad: cant[o.nombre],
        opcionesElegidas: [o.nombre],
        opcionesSel: [{ g: grupo.nombre, o: o.nombre }],
        opcionesTexto: o.nombre,
      }));
    if (items.length) onAgregar(items);
    onCerrar();
  }

  return (
    <Marco
      titulo={producto.nombre}
      sub={`Elige cuántas quieres · desde ${formatUsd(minUnit)} c/u`}
      onCerrar={onCerrar}
      footer={
        <>
          {err && <p className="mb-2 text-sm text-red-600">{err}</p>}
          <button
            onClick={confirmar}
            disabled={unidades === 0}
            className="flex w-full items-center justify-between rounded-2xl bg-marca px-5 py-3.5 font-bold text-marca-contraste shadow-flotante active:scale-[0.99] disabled:opacity-50"
          >
            <span>Agregar {unidades > 0 ? `${unidades} ` : ''}{unidades === 1 ? 'unidad' : 'unidades'}</span>
            <span>{precioDual(total, tasa)}</span>
          </button>
        </>
      }
    >
      <div className="mb-1 text-sm font-bold text-stone-800">{grupo.nombre}</div>
      <div className="space-y-1.5">
        {grupo.opciones.map((o) => {
          const q = cant[o.nombre] ?? 0;
          return (
            <div key={o.nombre} className={`flex items-center justify-between rounded-xl border-2 px-3 py-2 ${q > 0 ? 'border-marca bg-marca-claro' : 'border-stone-200'}`}>
              <div className="min-w-0">
                <p className="truncate text-sm font-semibold text-stone-700">{o.nombre}</p>
                {producto.precio_usd + o.precio_extra > 0 && (
                  <p className="text-xs font-bold text-marca-oscuro">{formatUsd(producto.precio_usd + o.precio_extra)} c/u</p>
                )}
              </div>
              <div className="flex items-center gap-2">
                <button onClick={() => set(o.nombre, -1)} disabled={q === 0} className="grid h-8 w-8 place-items-center rounded-full bg-stone-100 text-lg text-stone-600 disabled:opacity-40">−</button>
                <span className="w-5 text-center text-sm font-extrabold">{q}</span>
                <button onClick={() => set(o.nombre, 1)} className="grid h-8 w-8 place-items-center rounded-full bg-marca text-lg text-marca-contraste">+</button>
              </div>
            </div>
          );
        })}
      </div>
    </Marco>
  );
}

// ── Modo marcar (ej. arepas: contornos, 1 sola unidad) ──
function ModalMarcar({
  producto,
  grupos,
  tasa,
  onAgregar,
  onCerrar,
}: {
  producto: Producto;
  grupos: OpcionGrupo[];
  tasa: number | null;
  onAgregar: (items: ItemElegido[]) => void;
  onCerrar: () => void;
}) {
  const [sel, setSel] = useState<Record<number, string[]>>({});
  const [err, setErr] = useState<string | null>(null);

  function toggle(gi: number, g: OpcionGrupo, nombre: string) {
    setErr(null);
    setSel((prev) => {
      const cur = prev[gi] ?? [];
      if (g.tipo === 'single') return { ...prev, [gi]: [nombre] };
      const on = cur.includes(nombre);
      if (on) return { ...prev, [gi]: cur.filter((x) => x !== nombre) };
      if (g.max && cur.length >= g.max) return prev;
      return { ...prev, [gi]: [...cur, nombre] };
    });
  }

  const { extra, elegidas, elegidasSel, texto } = useMemo(() => {
    let extra = 0;
    const elegidas: string[] = [];
    const elegidasSel: { g: string; o: string }[] = [];
    const partes: string[] = [];
    grupos.forEach((g, gi) => {
      const nombres = sel[gi] ?? [];
      if (nombres.length) partes.push(`${g.nombre}: ${nombres.join(', ')}`);
      nombres.forEach((n) => {
        elegidas.push(n);
        elegidasSel.push({ g: g.nombre, o: n });
        const op = g.opciones.find((o) => o.nombre === n);
        if (op) extra += op.precio_extra;
      });
    });
    return { extra, elegidas, elegidasSel, texto: partes.join(' · ') };
  }, [sel, grupos]);

  const total = producto.precio_usd + extra;

  function confirmar() {
    for (let gi = 0; gi < grupos.length; gi++) {
      if (grupos[gi].obligatorio && !(sel[gi]?.length)) {
        setErr(`Elige una opción en "${grupos[gi].nombre}"`);
        return;
      }
    }
    onAgregar([{ producto_id: producto.id, nombre: producto.nombre, precio_usd: total, opcionesElegidas: elegidas, opcionesSel: elegidasSel, opcionesTexto: texto }]);
    onCerrar();
  }

  return (
    <Marco
      titulo={producto.nombre}
      sub="Arma tu pedido a tu gusto"
      onCerrar={onCerrar}
      footer={
        <>
          {err && <p className="mb-2 text-sm text-red-600">{err}</p>}
          <button onClick={confirmar} className="flex w-full items-center justify-between rounded-2xl bg-marca px-5 py-3.5 font-bold text-marca-contraste shadow-flotante active:scale-[0.99]">
            <span>Agregar</span>
            <span>{precioDual(total, tasa)}</span>
          </button>
        </>
      }
    >
      <div className="space-y-4">
        {grupos.map((g, gi) => {
          const cur = sel[gi] ?? [];
          return (
            <div key={gi}>
              <div className="mb-1.5 flex items-center gap-2">
                <h3 className="text-sm font-bold text-stone-800">{g.nombre}</h3>
                {g.obligatorio ? (
                  <span className="rounded-full bg-marca-claro px-2 py-0.5 text-[10px] font-bold text-marca-oscuro">Obligatorio</span>
                ) : (
                  <span className="text-[11px] text-stone-400">Opcional</span>
                )}
                {g.tipo === 'multi' && g.max ? <span className="text-[11px] text-stone-400">Hasta {g.max}</span> : null}
              </div>
              <div className="space-y-1.5">
                {g.opciones.map((o) => {
                  const on = cur.includes(o.nombre);
                  return (
                    <button
                      key={o.nombre}
                      type="button"
                      onClick={() => toggle(gi, g, o.nombre)}
                      className={`flex w-full items-center justify-between rounded-xl border-2 px-3 py-2.5 text-sm font-semibold transition ${on ? 'border-marca bg-marca-claro text-marca-oscuro' : 'border-stone-200 bg-white text-stone-600'}`}
                    >
                      <span className="flex items-center gap-2">
                        <span className={`grid h-5 w-5 place-items-center border-2 text-xs ${on ? 'border-marca bg-marca text-marca-contraste' : 'border-stone-300 text-transparent'} ${g.tipo === 'single' ? 'rounded-full' : 'rounded-md'}`}>
                          <Icono nombre="check" className="h-3 w-3" grosor={2.6} />
                        </span>
                        {o.nombre}
                      </span>
                      {o.precio_extra > 0 && <span className="text-xs font-bold text-marca-oscuro">+{formatUsd(o.precio_extra)}</span>}
                    </button>
                  );
                })}
              </div>
            </div>
          );
        })}
      </div>
    </Marco>
  );
}
