// Admin: gestión de productos (publicar, editar, ocultar, eliminar, subir fotos)
const { useState: uS_ap, useEffect: uE_ap, useRef: uR_ap, useMemo: uM_ap } = React;

const AP_FONT = 'Special Elite,monospace';
const AP_INPUT = { width: '100%', boxSizing: 'border-box', padding: 8, fontFamily: AP_FONT, fontSize: 14, border: '2px solid var(--ink)', background: '#fff' };
const AP_LABEL = { display: 'block', fontFamily: AP_FONT, fontSize: 12, fontWeight: 'bold', textTransform: 'uppercase', marginBottom: 4 };
const AP_BTN = (bg, color) => ({ background: bg, color: color || '#fff', border: '2px solid var(--ink)', padding: '6px 10px', cursor: 'pointer', fontFamily: AP_FONT, fontWeight: 'bold', fontSize: 12 });

const PRODUCTO_VACIO = { slug: '', nombre: '', sub: '', categoria: '', marca: '', 'año': '', piezas: '', precio: '', antes: '', sale: false, stock: 1, desc: '', oculto: false, fotos: [] };

// Reduce la foto en el navegador (máx. 1600px, JPEG) para que suba rápido
function reducirImagen(file) {
  return new Promise((resolve, reject) => {
    const url = URL.createObjectURL(file);
    const im = new Image();
    im.onload = () => {
      const k = Math.min(1, 1600 / Math.max(im.width, im.height));
      const c = document.createElement('canvas');
      c.width = Math.round(im.width * k);
      c.height = Math.round(im.height * k);
      const ctx = c.getContext('2d');
      ctx.fillStyle = '#fff';
      ctx.fillRect(0, 0, c.width, c.height);
      ctx.drawImage(im, 0, 0, c.width, c.height);
      URL.revokeObjectURL(url);
      c.toBlob(b => b ? resolve(b) : reject(new Error('No se pudo procesar la foto')), 'image/jpeg', 0.85);
    };
    im.onerror = () => { URL.revokeObjectURL(url); reject(new Error(`"${file.name}" no parece una imagen válida`)); };
    im.src = url;
  });
}

function FormularioProducto({ secret, inicial, categorias, marcas, onGuardado, onCancelar }) {
  const [f, setF] = uS_ap(inicial);
  const [subiendo, setSubiendo] = uS_ap(0);
  const [arrastrando, setArrastrando] = uS_ap(false);
  const [error, setError] = uS_ap('');
  const [guardando, setGuardando] = uS_ap(false);
  const inputFotos = uR_ap(null);
  const set = (k, v) => setF(prev => ({ ...prev, [k]: v }));

  const subirArchivos = async (lista) => {
    const archivos = Array.from(lista).filter(a => a.type.startsWith('image/'));
    if (!archivos.length) { setError('Elige archivos de imagen (JPG, PNG...)'); return; }
    setError('');
    for (const archivo of archivos) {
      setSubiendo(n => n + 1);
      try {
        const blob = await reducirImagen(archivo);
        const r = await fetch('/api/admin/upload-image', {
          method: 'POST',
          headers: { 'Content-Type': 'image/jpeg', 'x-admin-secret': secret },
          body: blob
        });
        const d = await r.json();
        if (!r.ok) throw new Error(d.error || 'Error subiendo la foto');
        setF(prev => ({ ...prev, fotos: [...prev.fotos, d.url] }));
      } catch (e) {
        setError(e.message);
      } finally {
        setSubiendo(n => n - 1);
      }
    }
  };

  const moverFoto = (i, dir) => setF(prev => {
    const fotos = prev.fotos.slice();
    const j = i + dir;
    if (j < 0 || j >= fotos.length) return prev;
    [fotos[i], fotos[j]] = [fotos[j], fotos[i]];
    return { ...prev, fotos };
  });
  const quitarFoto = (i) => setF(prev => ({ ...prev, fotos: prev.fotos.filter((_, k) => k !== i) }));

  const guardar = async () => {
    if (!f.nombre.trim()) { setError('Escribe el nombre del producto'); return; }
    if (f.precio === '' || isNaN(Number(f.precio))) { setError('Escribe un precio válido'); return; }
    if (!f.fotos.length) { setError('Agrega al menos una foto'); return; }
    if (subiendo) { setError('Espera a que terminen de subir las fotos'); return; }
    setGuardando(true);
    setError('');
    try {
      const { fotos, ...resto } = f;
      const r = await fetch('/api/admin/product-save', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ secret, producto: { ...resto, img: fotos[0], preview: fotos } })
      });
      const d = await r.json();
      if (!r.ok) throw new Error(d.error || 'Error guardando el producto');
      onGuardado(f.slug ? 'Producto actualizado' : 'Producto publicado');
    } catch (e) {
      setError(e.message);
      setGuardando(false);
    }
  };

  const campo = (label, k, extra = {}) => (
    <div style={extra.wrap}>
      <label style={AP_LABEL}>{label}</label>
      <input style={AP_INPUT} value={f[k]} onChange={e => set(k, e.target.value)} {...extra.input} />
    </div>
  );

  return (
    <div style={{ background: '#fff', border: '2px solid var(--ink)', padding: 24, marginBottom: 24 }}>
      <h3 style={{ fontFamily: 'Bungee,sans-serif', margin: '0 0 16px', color: 'var(--red)' }}>
        {f.slug ? 'EDITAR PRODUCTO' : 'NUEVO PRODUCTO'}
      </h3>

      <label style={AP_LABEL}>Fotos (la primera es la portada)</label>
      <div
        onDragOver={e => { e.preventDefault(); setArrastrando(true); }}
        onDragLeave={() => setArrastrando(false)}
        onDrop={e => { e.preventDefault(); setArrastrando(false); subirArchivos(e.dataTransfer.files); }}
        onClick={() => inputFotos.current && inputFotos.current.click()}
        style={{ border: '3px dashed var(--ink)', background: arrastrando ? '#f7c90a' : 'var(--paper)', padding: 20, textAlign: 'center', cursor: 'pointer', fontFamily: AP_FONT, marginBottom: 12 }}
      >
        📷 Arrastra tus fotos aquí o toca para elegirlas
        {subiendo > 0 && <div style={{ marginTop: 6, fontWeight: 'bold' }}>Subiendo {subiendo} foto(s)...</div>}
        <input ref={inputFotos} type="file" accept="image/*" multiple style={{ display: 'none' }}
          onChange={e => { subirArchivos(e.target.files); e.target.value = ''; }} />
      </div>
      {f.fotos.length > 0 && (
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10, marginBottom: 16 }}>
          {f.fotos.map((src, i) => (
            <div key={src + i} style={{ width: 110, border: '2px solid var(--ink)', background: 'var(--paper)', padding: 4, textAlign: 'center' }}>
              <img src={src} alt="" style={{ width: '100%', height: 90, objectFit: 'cover', display: 'block' }} />
              <div style={{ fontFamily: AP_FONT, fontSize: 10, margin: '2px 0' }}>{i === 0 ? '★ PORTADA' : `Foto ${i + 1}`}</div>
              <div style={{ display: 'flex', gap: 2, justifyContent: 'center' }}>
                <button type="button" disabled={i === 0} onClick={() => moverFoto(i, -1)} style={{ ...AP_BTN('var(--ink)'), padding: '2px 6px' }}>←</button>
                <button type="button" disabled={i === f.fotos.length - 1} onClick={() => moverFoto(i, 1)} style={{ ...AP_BTN('var(--ink)'), padding: '2px 6px' }}>→</button>
                <button type="button" onClick={() => quitarFoto(i)} style={{ ...AP_BTN('var(--red)'), padding: '2px 6px' }}>✕</button>
              </div>
            </div>
          ))}
        </div>
      )}

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 12 }}>
        {campo('Nombre *', 'nombre', { wrap: { gridColumn: '1 / -1' } })}
        {campo('Subtítulo (ej. Sabritas 2005 · Colección completa)', 'sub', { wrap: { gridColumn: '1 / -1' } })}
        <div>
          <label style={AP_LABEL}>Categoría</label>
          <input style={AP_INPUT} list="ap-categorias" value={f.categoria} onChange={e => set('categoria', e.target.value)} />
          <datalist id="ap-categorias">{categorias.map(c => <option key={c} value={c} />)}</datalist>
        </div>
        <div>
          <label style={AP_LABEL}>Marca</label>
          <input style={AP_INPUT} list="ap-marcas" value={f.marca} onChange={e => set('marca', e.target.value)} />
          <datalist id="ap-marcas">{marcas.map(c => <option key={c} value={c} />)}</datalist>
        </div>
        {campo('Año', 'año', { input: { type: 'number', min: 1900 } })}
        {campo('Piezas', 'piezas', { input: { type: 'number', min: 0 } })}
        {campo('Precio (MXN) *', 'precio', { input: { type: 'number', min: 0 } })}
        {campo('Stock (cuántos hay)', 'stock', { input: { type: 'number', min: 0 } })}
        {campo('Precio anterior (si está en oferta)', 'antes', { input: { type: 'number', min: 0 } })}
        <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontFamily: AP_FONT, alignSelf: 'end', paddingBottom: 8 }}>
          <input type="checkbox" checked={f.sale} onChange={e => set('sale', e.target.checked)} /> Marcar como oferta
        </label>
        <div style={{ gridColumn: '1 / -1' }}>
          <label style={AP_LABEL}>Descripción</label>
          <textarea style={{ ...AP_INPUT, minHeight: 90 }} value={f.desc} onChange={e => set('desc', e.target.value)} />
        </div>
        <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontFamily: AP_FONT, gridColumn: '1 / -1' }}>
          <input type="checkbox" checked={f.oculto} onChange={e => set('oculto', e.target.checked)} /> Ocultar en la tienda (borrador)
        </label>
      </div>

      {error && <p style={{ fontFamily: AP_FONT, color: 'var(--red)', fontWeight: 'bold' }}>{error}</p>}
      <div style={{ display: 'flex', gap: 10, marginTop: 16 }}>
        <button onClick={guardar} disabled={guardando || subiendo > 0} style={{ ...AP_BTN('#2a7a3a'), padding: '10px 20px', fontSize: 14, opacity: guardando || subiendo > 0 ? 0.6 : 1 }}>
          {guardando ? 'Guardando...' : (f.slug ? '💾 Guardar cambios' : '🚀 Publicar producto')}
        </button>
        <button onClick={onCancelar} style={{ ...AP_BTN('var(--ink)'), padding: '10px 20px', fontSize: 14 }}>Cancelar</button>
      </div>
    </div>
  );
}

function AdminProductos({ secret, onCambio }) {
  const [productos, setProductos] = uS_ap([]);
  const [cargando, setCargando] = uS_ap(true);
  const [busqueda, setBusqueda] = uS_ap('');
  const [editando, setEditando] = uS_ap(null);
  const [msg, setMsg] = uS_ap('');

  const cargar = async () => {
    try {
      const r = await fetch('/api/admin/products-list', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ secret })
      });
      const d = await r.json();
      if (!r.ok) throw new Error(d.error || 'No se pudieron cargar los productos');
      setProductos(d);
    } catch (e) {
      setMsg(e.message);
    } finally {
      setCargando(false);
    }
  };
  uE_ap(() => { cargar(); }, []);

  const aviso = (t) => { setMsg(t); setTimeout(() => setMsg(''), 3000); };

  const guardarDirecto = async (p, cambios) => {
    const fotos = p.preview && p.preview.length ? p.preview : [p.img];
    const producto = { ...p, ...cambios, img: p.img, preview: fotos };
    try {
      const r = await fetch('/api/admin/product-save', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ secret, producto })
      });
      const d = await r.json();
      if (!r.ok) throw new Error(d.error || 'Error guardando');
      aviso('Listo');
      cargar(); onCambio && onCambio();
    } catch (e) { aviso(e.message); }
  };

  const eliminar = async (p) => {
    if (!confirm(`¿Eliminar "${p.nombre}" de la tienda? Esta acción no se puede deshacer.`)) return;
    try {
      const r = await fetch('/api/admin/product-delete', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ secret, slug: p.slug })
      });
      const d = await r.json();
      if (!r.ok) throw new Error(d.error || 'Error eliminando');
      aviso('Producto eliminado');
      cargar(); onCambio && onCambio();
    } catch (e) { aviso(e.message); }
  };

  const abrirEditor = (p) => setEditando(p ? {
    ...PRODUCTO_VACIO, ...p,
    'año': p['año'] || '', piezas: p.piezas || '', antes: p.antes || '', sale: !!p.sale,
    fotos: p.preview && p.preview.length ? p.preview : (p.img ? [p.img] : [])
  } : { ...PRODUCTO_VACIO });

  const categorias = uM_ap(() => [...new Set(productos.map(p => p.categoria).filter(Boolean))].sort(), [productos]);
  const marcas = uM_ap(() => [...new Set(productos.map(p => p.marca).filter(Boolean))].sort(), [productos]);
  const filtrados = productos.filter(p => `${p.nombre} ${p.sub} ${p.marca} ${p.categoria}`.toLowerCase().includes(busqueda.toLowerCase()));

  return (
    <div style={{ marginBottom: 40 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 10, marginBottom: 16 }}>
        <h2 style={{ fontFamily: 'Oswald,sans-serif', fontSize: 24, textTransform: 'uppercase', letterSpacing: 2, margin: 0 }}>🛍️ Productos de la tienda</h2>
        <button onClick={() => abrirEditor(null)} style={{ ...AP_BTN('var(--red)'), padding: '10px 18px', fontSize: 14 }}>＋ Nuevo producto</button>
      </div>

      {msg && <div style={{ background: '#f7c90a', color: '#1a1611', padding: 10, fontFamily: AP_FONT, fontWeight: 'bold', marginBottom: 12 }}>{msg}</div>}

      {editando && (
        <FormularioProducto
          key={editando.slug || 'nuevo'}
          secret={secret} inicial={editando} categorias={categorias} marcas={marcas}
          onCancelar={() => setEditando(null)}
          onGuardado={(t) => { setEditando(null); aviso(t); cargar(); onCambio && onCambio(); }}
        />
      )}

      <input style={{ ...AP_INPUT, marginBottom: 12 }} placeholder="🔍 Buscar por nombre, marca o categoría..." value={busqueda} onChange={e => setBusqueda(e.target.value)} />

      {cargando ? <p style={{ fontFamily: AP_FONT }}>Cargando productos...</p> : (
        <div style={{ overflowX: 'auto' }}>
          <table style={{ width: '100%', borderCollapse: 'collapse', fontFamily: AP_FONT, fontSize: 14, border: '2px solid var(--ink)' }}>
            <thead>
              <tr style={{ background: 'var(--ink)', color: 'var(--paper)' }}>
                <th style={{ padding: 10, textAlign: 'left' }}>Foto</th>
                <th style={{ padding: 10, textAlign: 'left' }}>Producto</th>
                <th style={{ padding: 10, textAlign: 'right' }}>Precio</th>
                <th style={{ padding: 10, textAlign: 'center' }}>Stock</th>
                <th style={{ padding: 10, textAlign: 'center' }}>Estado</th>
                <th style={{ padding: 10, textAlign: 'center' }}>Acciones</th>
              </tr>
            </thead>
            <tbody>
              {filtrados.map(p => (
                <tr key={p.slug} style={{ borderBottom: '1px solid #ccc', background: p.oculto ? '#eee' : '#fff' }}>
                  <td style={{ padding: 8 }}><img src={p.img} alt="" style={{ width: 44, height: 44, objectFit: 'cover', border: '1px solid var(--ink)' }} /></td>
                  <td style={{ padding: 8 }}><strong>{p.nombre}</strong><br /><small style={{ color: '#666' }}>{p.marca} · {p.categoria}</small></td>
                  <td style={{ padding: 8, textAlign: 'right' }}>${p.precio}</td>
                  <td style={{ padding: 8, textAlign: 'center' }}>{p.stock}</td>
                  <td style={{ padding: 8, textAlign: 'center' }}>
                    {p.oculto ? <span style={{ color: '#666', fontWeight: 'bold' }}>Oculto</span>
                      : p.stock > 0 ? <span style={{ color: '#2a7a3a', fontWeight: 'bold' }}>Público</span>
                      : <span style={{ color: 'var(--red)', fontWeight: 'bold' }}>Agotado</span>}
                  </td>
                  <td style={{ padding: 8, textAlign: 'center', whiteSpace: 'nowrap' }}>
                    <button onClick={() => { abrirEditor(p); window.scrollTo({ top: 0, behavior: 'smooth' }); }} style={AP_BTN('#1a5fb4')}>Editar</button>{' '}
                    <button onClick={() => guardarDirecto(p, { oculto: !p.oculto })} style={AP_BTN('var(--ink)')}>{p.oculto ? 'Mostrar' : 'Ocultar'}</button>{' '}
                    <button onClick={() => eliminar(p)} style={AP_BTN('var(--red)')}>Eliminar</button>
                  </td>
                </tr>
              ))}
              {filtrados.length === 0 && <tr><td colSpan="6" style={{ padding: 16, textAlign: 'center' }}>No hay productos que coincidan.</td></tr>}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { AdminProductos });
