import { useState } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { formatUsd, grupoDeCategoria, GRUPOS_CATEGORIAS, textoHorarioCategoria, type Categoria, type Producto } from '@gustito/shared';
import { Icono } from '@gustito/shared/iconos';
import { supabase } from '../lib/supabase';
import { subirImagen } from '../lib/storage';
import OpcionesProductoModal from './OpcionesProductoModal';
import ImportarMenuModal, { type ResultadoIA } from './ImportarMenuModal';
import HorarioCategoria from '../components/HorarioCategoria';

export default function Menu({
  restauranteId,
  marca = '#FBBF24',
  txtMarca = '#0D0F1E',
  acento = '#FBBF24',
}: {
  restauranteId: string;
  marca?: string;
  txtMarca?: string;
  acento?: string;
}) {
  const qc = useQueryClient();
  const [nombre, setNombre] = useState('');
  const [precio, setPrecio] = useState('');
  const [categoriaNombre, setCategoriaNombre] = useState('');
  const [resultadoIA, setResultadoIA] = useState<ResultadoIA | null>(null);
  const [importando, setImportando] = useState(false);
  const [errorIA, setErrorIA] = useState<string | null>(null);
  const [editCatId, setEditCatId] = useState<string | null>(null);
  const [editCatNombre, setEditCatNombre] = useState('');
  const [opcModal, setOpcModal] = useState<Producto | null>(null);
  const [horarioDe, setHorarioDe] = useState<Categoria | null>(null);
  const [verArchivados, setVerArchivados] = useState(false);

  const dataQ = useQuery({
    queryKey: ['menu', restauranteId],
    queryFn: async () => {
      const [cats, prods] = await Promise.all([
        supabase.from('categorias').select('*').eq('restaurante_id', restauranteId).order('orden'),
        supabase.from('productos').select('*').eq('restaurante_id', restauranteId).order('orden'),
      ]);
      if (cats.error) throw cats.error;
      if (prods.error) throw prods.error;
      return {
        cats: (cats.data ?? []) as unknown as Categoria[],
        prods: (prods.data ?? []) as unknown as Producto[],
      };
    },
  });

  function refrescar() {
    qc.invalidateQueries({ queryKey: ['menu', restauranteId] });
  }

  async function toggleCocina(id: string, actual: boolean) {
    const { error } = await supabase.from('categorias').update({ a_cocina: !actual }).eq('id', id);
    if (error) alert(error.message);
    else refrescar();
  }

  async function renombrarCategoria(id: string, nombre: string) {
    const n = nombre.trim();
    if (!n) return;
    const { error } = await supabase.from('categorias').update({ nombre: n }).eq('id', id);
    if (error) alert(error.message);
    else {
      setEditCatId(null);
      refrescar();
    }
  }

  async function toggleDisponible(p: Producto) {
    const { error } = await supabase
      .from('productos')
      .update({ disponible: !p.disponible })
      .eq('id', p.id);
    if (error) alert(error.message);
    else refrescar();
  }

  async function guardarPrecio(p: Producto, nuevo: number) {
    if (Number.isNaN(nuevo) || nuevo < 0 || nuevo === p.precio_usd) return;
    const { error } = await supabase.from('productos').update({ precio_usd: nuevo }).eq('id', p.id);
    if (error) alert(error.message);
    else refrescar();
  }

  // Sacar del menu NO borra. Antes esto hacia un DELETE de verdad, y eso tenia
  // dos problemas: los pedidos ya vendidos perdian el enlace con el producto
  // (y con el, los reportes que cuentan por producto), y las recetas de costos
  // se borraban en cascada sin decir una palabra. Ahora se archiva: el cliente
  // deja de verlo, el negocio no pierde nada y se puede devolver cuando quiera.
  // Por eso tampoco pregunta "seguro?": no hay nada que lamentar.
  async function sacarDelMenu(p: Producto, sacar: boolean) {
    const { error } = await supabase.from('productos').update({ archivado: sacar }).eq('id', p.id);
    if (error) alert(error.message);
    else refrescar();
  }

  async function subirFotoProducto(p: Producto, file?: File) {
    if (!file) return;
    try {
      const url = await subirImagen(file, 'productos', restauranteId);
      const { error } = await supabase.from('productos').update({ foto_url: url }).eq('id', p.id);
      if (error) throw error;
      refrescar();
    } catch (e) {
      alert('No se pudo subir la foto: ' + (e as Error).message);
    }
  }

  async function crearProducto() {
    const precioNum = parseFloat(precio);
    if (!nombre.trim() || Number.isNaN(precioNum)) {
      alert('Pon nombre y precio validos');
      return;
    }
    // Resolver la categoria por nombre: reusar si existe, crear si no.
    let categoria_id: string | null = null;
    const catNombre = categoriaNombre.trim();
    if (catNombre) {
      const cats = dataQ.data?.cats ?? [];
      const existente = cats.find((c) => c.nombre.trim().toLowerCase() === catNombre.toLowerCase());
      if (existente) {
        categoria_id = existente.id;
      } else {
        const { data, error } = await supabase
          .from('categorias')
          .insert({ restaurante_id: restauranteId, nombre: catNombre, orden: cats.length + 1, grupo: grupoDeCategoria(catNombre) })
          .select()
          .single();
        if (error) {
          alert(error.message);
          return;
        }
        categoria_id = (data as { id: string }).id;
      }
    }
    const { error } = await supabase.from('productos').insert({
      restaurante_id: restauranteId,
      categoria_id,
      nombre: nombre.trim(),
      precio_usd: precioNum,
      disponible: true,
    });
    if (error) {
      alert(error.message);
      return;
    }
    setNombre('');
    setPrecio('');
    setCategoriaNombre('');
    refrescar();
  }

  function fileToBase64(file: File): Promise<{ b64: string; mime: string }> {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => {
        const res = reader.result as string;
        resolve({ b64: res.slice(res.indexOf(',') + 1), mime: file.type || 'image/jpeg' });
      };
      reader.onerror = reject;
      reader.readAsDataURL(file);
    });
  }

  async function importarFoto(file?: File) {
    if (!file) return;
    setImportando(true);
    setErrorIA(null);
    try {
      const { b64, mime } = await fileToBase64(file);
      const { data, error } = await supabase.functions.invoke('importar-menu-ia', {
        body: { imagen_base64: b64, mime_type: mime },
      });
      if (error) {
        let msg = error.message;
        try {
          const ctx = (error as { context?: Response }).context;
          const body = ctx ? await ctx.json() : null;
          if (body?.error) msg = body.error as string;
        } catch {
          /* se queda con el mensaje generico */
        }
        throw new Error(msg);
      }
      const res = data as ResultadoIA;
      if (!res?.productos?.length) {
        setErrorIA('La IA no encontro productos. Prueba con una foto mas clara y de frente.');
      } else {
        setResultadoIA(res);
      }
    } catch (e) {
      setErrorIA((e as Error).message);
    } finally {
      setImportando(false);
    }
  }

  if (dataQ.isLoading) return <p className="text-niebla">Cargando menu...</p>;
  if (dataQ.error) return <p className="text-red-400">{(dataQ.error as Error).message}</p>;

  const { cats, prods } = dataQ.data!;

  return (
    <div className="space-y-5">
      <h1 className="text-xl font-extrabold">Menú</h1>

      {/* Importar con IA */}
      <div className="rounded-2xl border p-4" style={{ borderColor: acento + '55', background: acento + '14' }}>
        <h2 className="font-bold" style={{ color: acento }}>Importar menú con una foto</h2>
        <p className="text-xs text-niebla mb-2">
          Toma o sube una foto de tu menú y la IA lo digitaliza por ti.
        </p>
        <div className="flex flex-wrap gap-2">
          <label className="btn inline-flex cursor-pointer items-center gap-1.5" style={{ background: marca, color: txtMarca }}>
            <Icono nombre="camara" className="h-5 w-5" />
            {importando ? 'Leyendo...' : 'Tomar foto'}
            <input
              type="file"
              accept="image/*"
              capture="environment"
              className="hidden"
              disabled={importando}
              onChange={(e) => importarFoto(e.target.files?.[0])}
            />
          </label>
          <label className="btn inline-flex cursor-pointer items-center gap-1.5 bg-white/10 text-white ring-1 ring-white/15">
            <Icono nombre="camara" className="h-5 w-5" />
            Subir del teléfono
            <input
              type="file"
              accept="image/*"
              className="hidden"
              disabled={importando}
              onChange={(e) => importarFoto(e.target.files?.[0])}
            />
          </label>
        </div>
        {errorIA && <p className="text-sm text-red-400 mt-2">{errorIA}</p>}
      </div>

      {/* Nuevo producto */}
      <div className="rounded-2xl border border-white/10 bg-superficie p-4">
        <h2 className="font-bold mb-2">Agregar producto</h2>
        <div className="grid grid-cols-1 sm:grid-cols-4 gap-2">
          <input
            className="input sm:col-span-2"
            placeholder="Nombre"
            value={nombre}
            onChange={(e) => setNombre(e.target.value)}
          />
          <input
            className="input"
            placeholder="Precio USD"
            inputMode="decimal"
            value={precio}
            onChange={(e) => setPrecio(e.target.value)}
          />
          <input
            className="input"
            placeholder="Categoria (o escribela)"
            value={categoriaNombre}
            onChange={(e) => setCategoriaNombre(e.target.value)}
          />
          <select
            className="input"
            value=""
            onChange={(e) => e.target.value && setCategoriaNombre(e.target.value)}
          >
            <option value="">Elegir categoria...</option>
            {/* Primero las categorias que YA tiene el negocio: ofrecer solo la
                lista generica hacia categorias nuevas que no son de su carta y
                el menu se le llena de secciones repetidas. */}
            {cats.length > 0 && (
              <optgroup label="Las de tu menú">
                {cats.map((c) => (
                  <option key={c.id} value={c.nombre}>
                    {c.nombre}
                  </option>
                ))}
              </optgroup>
            )}
            <optgroup label="Crear una nueva">
              {GRUPOS_CATEGORIAS.filter((g) => !cats.some((c) => c.nombre.toLowerCase() === g.grupo.toLowerCase())).map((g) => (
                <option key={g.grupo} value={g.grupo}>
                  {g.grupo}
                </option>
              ))}
            </optgroup>
          </select>
        </div>
        <button onClick={crearProducto} className="btn mt-3" style={{ background: marca, color: txtMarca }}>
          Agregar
        </button>
      </div>

      {/* Listado por categoria */}
      {cats.map((c) => {
        const items = prods
          .filter((p) => p.categoria_id === c.id && !p.archivado)
          .sort((a, b) => Number(b.disponible) - Number(a.disponible));
        // Las categorias sin productos TAMBIEN se muestran: escondidas no habia
        // forma de verlas ni de renombrarlas, y seguian saliendo en el selector
        // de arriba como si el menu las tuviera.
        return (
          <div key={c.id}>
            <div className="mb-2 flex items-center gap-2">
              {editCatId === c.id ? (
                <>
                  <input
                    className="input flex-1"
                    value={editCatNombre}
                    autoFocus
                    onChange={(e) => setEditCatNombre(e.target.value)}
                    onKeyDown={(e) => {
                      if (e.key === 'Enter') renombrarCategoria(c.id, editCatNombre);
                      if (e.key === 'Escape') setEditCatId(null);
                    }}
                  />
                  <button onClick={() => renombrarCategoria(c.id, editCatNombre)} className="btn" style={{ background: marca, color: txtMarca }}>
                    Guardar
                  </button>
                  <button onClick={() => setEditCatId(null)} className="text-sm text-niebla">
                    Cancelar
                  </button>
                </>
              ) : (
                <>
                  <h3 className="font-bold text-white">{c.nombre}</h3>
                  <button
                    onClick={() => {
                      setEditCatId(c.id);
                      setEditCatNombre(c.nombre);
                    }}
                    className="text-niebla hover:text-white"
                    title="Renombrar categoria"
                    aria-label="Renombrar categoria"
                  >
                    <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                      <path d="M12 20h9" />
                      <path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z" />
                    </svg>
                  </button>
                  <button
                    onClick={() => setHorarioDe(c)}
                    className="ml-auto shrink-0 rounded-full px-2.5 py-1 text-[11px] font-bold ring-1 ring-white/20 transition hover:bg-white/5"
                    style={textoHorarioCategoria(c) ? { color: '#7DD3FC' } : { color: 'rgba(255,255,255,.55)' }}
                    title="¿Esta categoría se vende solo ciertos días u horas? Solo afecta a quien pide por internet."
                  >
                    {textoHorarioCategoria(c) ?? 'Sin horario'}
                  </button>
                  <button
                    onClick={() => toggleCocina(c.id, c.a_cocina)}
                    className="shrink-0 rounded-full px-2.5 py-1 text-[11px] font-bold ring-1 transition"
                    style={
                      c.a_cocina
                        ? { background: 'rgba(245,158,11,.15)', color: '#FCD34D', ['--tw-ring-color' as string]: 'rgba(245,158,11,.4)' }
                        : { color: 'rgba(255,255,255,.55)', ['--tw-ring-color' as string]: 'rgba(255,255,255,.2)' }
                    }
                    title="¿Esta categoría va a la cocina? Las bebidas, no."
                  >
                    {c.a_cocina ? 'Va a cocina' : 'No va a cocina'}
                  </button>
                </>
              )}
            </div>
            <div className="space-y-2">
              {items.length === 0 && (
                <p className="rounded-xl border border-dashed border-white/15 bg-superficie/50 p-3 text-sm text-niebla">
                  Esta categoría no tiene ningún plato en el menú. Agrega uno arriba eligiéndola, o cámbiale el nombre para reusarla.
                </p>
              )}
              {items.map((p) => (
                <div key={p.id} className="rounded-xl border border-white/10 bg-superficie p-3">
                  <div className="flex items-start gap-2">
                    <label
                      className="relative grid h-14 w-14 shrink-0 cursor-pointer place-items-center overflow-hidden rounded-lg bg-white/5 text-lg ring-1 ring-white/10"
                      title="Subir o cambiar la foto del plato"
                    >
                      {p.foto_url ? (
                        <img src={p.foto_url} className="h-full w-full object-cover" alt="" />
                      ) : (
                        <Icono nombre="camara" className="h-5 w-5" />
                      )}
                      <input
                        type="file"
                        accept="image/*"
                        className="hidden"
                        onChange={(e) => subirFotoProducto(p, e.target.files?.[0])}
                      />
                    </label>
                    <div className="min-w-0 flex-1">
                      <p className="truncate font-medium">{p.nombre}</p>
                      <p className="text-xs text-niebla">{formatUsd(p.precio_usd)}</p>
                      {!p.foto_url && <p className="text-[11px]" style={{ color: acento }}>Toca la foto para agregar imagen</p>}
                    </div>
                    <button
                      onClick={() => sacarDelMenu(p, true)}
                      className="shrink-0 rounded-lg p-2 text-niebla hover:bg-white/10"
                      title="Sacar del menú (se puede devolver)"
                      aria-label="Sacar del menú"
                    >
                      <svg
                        width="18"
                        height="18"
                        viewBox="0 0 24 24"
                        fill="none"
                        stroke="currentColor"
                        strokeWidth="2"
                        strokeLinecap="round"
                        strokeLinejoin="round"
                      >
                        <path d="M3 7h18v3H3zM5 10v10h14V10M10 14h4" />
                      </svg>
                    </button>
                  </div>
                  <div className="mt-2 flex items-center gap-2">
                    {(p.opciones ?? []).some((g) => g.tipo === 'cantidad') ? (
                      <span className="text-xs text-niebla">
                        Precio: <span className="font-semibold" style={{ color: acento }}>en cada opción</span>
                      </span>
                    ) : (
                      <label className="text-xs text-niebla">
                        Precio $
                        <input
                          className="input ml-1 w-24"
                          type="number"
                          step="0.5"
                          defaultValue={p.precio_usd}
                          onBlur={(e) => guardarPrecio(p, parseFloat(e.target.value))}
                        />
                      </label>
                    )}
                    <button
                      onClick={() => setOpcModal(p)}
                      className="rounded-lg border px-2.5 py-1.5 text-xs font-bold"
                      style={{ color: acento, borderColor: acento + '4D' }}
                    >
                      Opciones{p.opciones?.length ? ` · ${p.opciones.length}` : ''}
                    </button>
                    <button
                      onClick={() => toggleDisponible(p)}
                      className={`btn ml-auto ${
                        p.disponible ? 'bg-green-500/15 text-green-300' : 'bg-white/10 text-niebla'
                      }`}
                    >
                      {p.disponible ? 'Disponible' : 'Agotado'}
                    </button>
                  </div>
                </div>
              ))}
            </div>
          </div>
        );
      })}

      {/* Lo que se saco del menu. El cliente no lo ve, pero el dueño si, para
          poder devolverlo cuando quiera. Nada de esto se borro: los pedidos
          viejos siguen enlazados y las recetas de costos, intactas. */}
      {prods.some((p) => p.archivado) && (
        <div className="rounded-2xl bg-white/5 p-3">
          <button
            onClick={() => setVerArchivados((v) => !v)}
            className="flex w-full items-center justify-between text-left"
          >
            <span className="font-medium text-niebla">
              Fuera del menú ({prods.filter((p) => p.archivado).length})
            </span>
            <span className="text-niebla">{verArchivados ? '▴' : '▾'}</span>
          </button>
          {verArchivados && (
            <>
              <p className="mt-1 text-xs text-niebla">
                El cliente no los ve. No se borraron: sus ventas y sus recetas de costos siguen ahí.
              </p>
              <div className="mt-3 space-y-2">
                {prods
                  .filter((p) => p.archivado)
                  .map((p) => (
                    <div key={p.id} className="flex items-center gap-2 rounded-xl bg-white/5 p-2">
                      <div className="min-w-0 flex-1">
                        <p className="truncate">{p.nombre}</p>
                        <p className="text-xs text-niebla">
                          {cats.find((c) => c.id === p.categoria_id)?.nombre ?? 'Sin categoría'} · {formatUsd(p.precio_usd)}
                        </p>
                      </div>
                      <button
                        onClick={() => sacarDelMenu(p, false)}
                        className="btn shrink-0 text-sm"
                        style={{ background: marca, color: txtMarca }}
                      >
                        Devolver al menú
                      </button>
                    </div>
                  ))}
              </div>
            </>
          )}
        </div>
      )}

      {opcModal && (
        <OpcionesProductoModal
          producto={opcModal}
          onCerrar={() => setOpcModal(null)}
          onGuardado={refrescar}
        />
      )}
      {horarioDe && (
        <HorarioCategoria
          categoria={horarioDe}
          marca={marca}
          txtMarca={txtMarca}
          onCerrar={(cambio) => {
            setHorarioDe(null);
            if (cambio) refrescar();
          }}
        />
      )}
      {resultadoIA && (
        <ImportarMenuModal
          restauranteId={restauranteId}
          resultado={resultadoIA}
          catsExistentes={cats}
          onCerrar={() => setResultadoIA(null)}
          onImportado={refrescar}
        />
      )}
    </div>
  );
}
