// admin.jsx — Panel de administración del catálogo de arriendo

function AdminApp() {
  const supa = window.supabaseClient;
  const [session, setSession] = React.useState(undefined);

  React.useEffect(() => {
    supa.auth.getSession().then(({ data }) => setSession(data.session));
    const { data: sub } = supa.auth.onAuthStateChange((_e, sess) => setSession(sess));
    return () => sub.subscription.unsubscribe();
  }, []);

  if (session === undefined) return <div className="adm-loading">Cargando…</div>;
  if (!session) return <AdminLogin />;
  return <AdminDashboard session={session} />;
}

function AdminLogin() {
  const supa = window.supabaseClient;
  const [email, setEmail] = React.useState('');
  const [pw, setPw] = React.useState('');
  const [err, setErr] = React.useState('');
  const [loading, setLoading] = React.useState(false);

  const submit = async (e) => {
    e.preventDefault();
    setErr(''); setLoading(true);
    const { error } = await supa.auth.signInWithPassword({ email, password: pw });
    if (error) setErr(error.message);
    setLoading(false);
  };

  return (
    <div className="adm-shell adm-login">
      <form className="adm-card" onSubmit={submit}>
        <div className="adm-brand">PERTEC · ADMIN</div>
        <h1>Acceso al catálogo</h1>
        <p className="adm-sub">Ingrese sus credenciales para gestionar los equipos de arriendo.</p>
        <label>Email
          <input type="email" required autoFocus value={email} onChange={e=>setEmail(e.target.value)} placeholder="usuario@pertec.cl" />
        </label>
        <label>Password
          <input type="password" required value={pw} onChange={e=>setPw(e.target.value)} placeholder="••••••••" />
        </label>
        {err && <div className="adm-err">{err}</div>}
        <button type="submit" className="adm-btn primary" disabled={loading}>
          {loading ? 'Verificando…' : 'Entrar'}
        </button>
        <a href="/" className="adm-back">← Volver al sitio</a>
      </form>
    </div>
  );
}

function AdminDashboard({ session }) {
  const supa = window.supabaseClient;
  const [section, setSection] = React.useState(() => {
    return localStorage.getItem('adm-section') || 'catalogo';
  });
  const [solicitudesNew, setSolicitudesNew] = React.useState(0);

  React.useEffect(() => {
    localStorage.setItem('adm-section', section);
  }, [section]);

  // Conteo de solicitudes nuevas (Edge Function bypassa RLS Phase 3)
  React.useEffect(() => {
    const refresh = async () => {
      const { data, error } = await supa.functions.invoke('admin-solicitudes', {
        body: { action: 'count', estado: 'nuevo' },
      });
      if (!error && data && typeof data.count === 'number') {
        setSolicitudesNew(data.count);
      }
    };
    refresh();
    const id = setInterval(refresh, 30000);
    return () => clearInterval(id);
  }, []);

  return (
    <div className="adm-shell">
      <header className="adm-header">
        <div className="adm-header-l">
          <span className="adm-brand">PERTEC · ADMIN</span>
          <span className="adm-pill">{session.user.email}</span>
        </div>
        <div className="adm-header-r">
          <a href="/" className="adm-link">Ver sitio</a>
          <button className="adm-btn ghost" onClick={() => supa.auth.signOut()}>Cerrar sesión</button>
        </div>
      </header>

      <nav className="adm-nav">
        <button className={`adm-nav-item ${section==='catalogo'?'active':''}`} onClick={()=>setSection('catalogo')}>
          <i data-lucide="boxes"></i> Catálogo
        </button>
        <button className={`adm-nav-item ${section==='casos'?'active':''}`} onClick={()=>setSection('casos')}>
          <i data-lucide="award"></i> Casos
        </button>
        <button className={`adm-nav-item ${section==='solicitudes'?'active':''}`} onClick={()=>setSection('solicitudes')}>
          <i data-lucide="inbox"></i> Solicitudes
          {solicitudesNew > 0 && <span className="adm-nav-badge">{solicitudesNew}</span>}
        </button>
        <button className={`adm-nav-item ${section==='config'?'active':''}`} onClick={()=>setSection('config')}>
          <i data-lucide="settings"></i> Configuración
        </button>
      </nav>

      {section === 'catalogo' && <CatalogoSection />}
      {section === 'casos' && <CasosSection />}
      {section === 'solicitudes' && <SolicitudesSection onChange={() => {/* refresh badge */}} />}
      {section === 'config' && <ConfigSection />}
    </div>
  );
}

function CatalogoSection() {
  const supa = window.supabaseClient;
  const [equipos, setEquipos] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [editing, setEditing] = React.useState(null);
  const [filtro, setFiltro] = React.useState('producto');

  const load = async () => {
    setLoading(true);
    const { data, error } = await supa
      .from('equipos')
      .select('*')
      .order('orden', { ascending: true })
      .order('created_at', { ascending: true });
    if (error) console.error(error);
    setEquipos(data || []);
    setLoading(false);
  };

  React.useEffect(() => { load(); }, []);

  const visibleEquipos = filtro === 'all'
    ? equipos
    : equipos.filter(e => (e.categoria || 'producto') === filtro);
  const counts = {
    producto: equipos.filter(e => (e.categoria || 'producto') === 'producto').length,
    servicio: equipos.filter(e => e.categoria === 'servicio').length,
  };

  const onDelete = async (eq) => {
    if (!confirm(`¿Eliminar "${eq.nombre}"?`)) return;
    // Operaciones via Edge Function (bypassa RLS de Phase 3).
    if (eq.imagen_url) {
      const path = eq.imagen_url.split('/equipos/')[1];
      if (path) {
        await supa.functions.invoke('admin-equipos', {
          body: { action: 'delete-image', path },
        });
      }
    }
    const { data, error } = await supa.functions.invoke('admin-equipos', {
      body: { action: 'delete', id: eq.id },
    });
    if (error) { alert('Error: ' + (error.message || error)); return; }
    if (data && data.error) { alert('Error: ' + data.error); return; }
    load();
  };

  React.useEffect(() => { window.lucide && window.lucide.createIcons(); }, []);

  return (
    <>
      <main className="adm-main">
        <div className="adm-toolbar">
          <div>
            <h2>Catálogo</h2>
            <p className="adm-sub">{equipos.length} ítem{equipos.length === 1 ? '' : 's'} totales · {counts.producto} producto{counts.producto === 1 ? '' : 's'} · {counts.servicio} servicio{counts.servicio === 1 ? '' : 's'}</p>
          </div>
          <button className="adm-btn primary" onClick={() => setEditing({ categoria: filtro === 'servicio' ? 'servicio' : 'producto' })}>+ Agregar {filtro === 'servicio' ? 'servicio' : 'producto'}</button>
        </div>

        <div className="adm-cat-toggle">
          <button className={`adm-cat-pill ${filtro === 'producto' ? 'active' : ''}`} onClick={() => setFiltro('producto')}>Productos <span>{counts.producto}</span></button>
          <button className={`adm-cat-pill ${filtro === 'servicio' ? 'active' : ''}`} onClick={() => setFiltro('servicio')}>Servicios <span>{counts.servicio}</span></button>
          <button className={`adm-cat-pill ${filtro === 'all' ? 'active' : ''}`} onClick={() => setFiltro('all')}>Todos</button>
        </div>

        {loading ? (
          <div className="adm-loading">Cargando…</div>
        ) : visibleEquipos.length === 0 ? (
          <div className="adm-empty">
            <p>No hay {filtro === 'servicio' ? 'servicios' : filtro === 'producto' ? 'productos' : 'ítems'} cargados aún.</p>
            <button className="adm-btn primary" onClick={() => setEditing({ categoria: filtro === 'servicio' ? 'servicio' : 'producto' })}>Crear el primero</button>
          </div>
        ) : (
          <div className="adm-grid">
            {visibleEquipos.map(e => (
              <div key={e.id} className="adm-card-eq">
                <div className="adm-card-img">
                  {e.imagen_url
                    ? <img src={e.imagen_url} alt={e.nombre} />
                    : <div className="adm-noimg">Sin imagen</div>}
                  {e.destacado && <div className="adm-tag dest">★ Destacado</div>}
                  {!e.disponible && <div className="adm-tag bad">No disponible</div>}
                </div>
                <div className="adm-card-body">
                  <h3>{e.nombre}</h3>
                  <p>{e.descripcion_corta || <span className="adm-mute">Sin descripción</span>}</p>
                  <div className="adm-meta">
                    <span className={`adm-cat-badge ${(e.categoria || 'producto') === 'servicio' ? 'serv' : 'prod'}`}>{(e.categoria || 'producto') === 'servicio' ? 'Servicio' : 'Producto'}</span>
                    <span>{e.tipo || '—'}</span>
                    {e.ancho_correa_max && <><span>·</span><span>{e.ancho_correa_max}</span></>}
                    <span>·</span>
                    <span>#{e.orden ?? 0}</span>
                  </div>
                  <div className="adm-card-actions">
                    <button className="adm-btn ghost" onClick={() => setEditing(e)}>Editar</button>
                    <button className="adm-btn danger" onClick={() => onDelete(e)}>Eliminar</button>
                  </div>
                </div>
              </div>
            ))}
          </div>
        )}
      </main>

      {editing !== null && (
        <EquipoForm
          equipo={editing}
          onClose={() => setEditing(null)}
          onSaved={() => { setEditing(null); load(); }}
        />
      )}
    </>
  );
}

function EquipoForm({ equipo, onClose, onSaved }) {
  const supa = window.supabaseClient;
  const isNew = !equipo.id;
  const [f, setF] = React.useState({
    nombre: equipo.nombre || '',
    categoria: equipo.categoria || 'producto',
    descripcion_corta: equipo.descripcion_corta || '',
    descripcion_larga: equipo.descripcion_larga || '',
    tipo: equipo.tipo || '',
    ancho_correa_max: equipo.ancho_correa_max || '',
    imagen_url: equipo.imagen_url || '',
    imagenes: Array.isArray(equipo.imagenes) ? equipo.imagenes : [],
    descripciones_extra: Array.isArray(equipo.descripciones_extra) ? equipo.descripciones_extra : [],
    especificaciones: Array.isArray(equipo.especificaciones) ? equipo.especificaciones : [],
    destacado: !!equipo.destacado,
    disponible: equipo.disponible ?? true,
    orden: equipo.orden ?? 0,
  });
  const [uploading, setUploading] = React.useState(false);
  const [saving, setSaving] = React.useState(false);
  const [err, setErr] = React.useState('');

  const upd = (k, v) => setF(s => ({ ...s, [k]: v }));

  const upload = async (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setUploading(true); setErr('');
    try {
      // Lee el archivo a base64 y delega el upload a la Edge Function
      // (bypassa la RLS estricta del bucket equipos).
      const dataBase64 = await new Promise((resolve, reject) => {
        const r = new FileReader();
        r.onload = () => {
          const s = String(r.result || '');
          resolve(s.includes(',') ? s.split(',')[1] : s);
        };
        r.onerror = () => reject(r.error);
        r.readAsDataURL(file);
      });
      const { data, error } = await supa.functions.invoke('admin-equipos', {
        body: {
          action: 'upload-image',
          filename: file.name,
          contentType: file.type || 'image/jpeg',
          dataBase64,
        },
      });
      if (error) throw new Error(error.message || 'fallo al subir');
      if (data && data.error) throw new Error(data.error);
      upd('imagen_url', data.publicUrl);
    } catch (err) {
      setErr('Error subiendo imagen: ' + (err.message || err));
    } finally {
      setUploading(false);
    }
  };

  const removeImg = async () => {
    if (!f.imagen_url) return;
    const path = f.imagen_url.split('/equipos/')[1];
    if (path) {
      await supa.functions.invoke('admin-equipos', {
        body: { action: 'delete-image', path },
      });
    }
    upd('imagen_url', '');
  };

  const uploadGallery = async (e) => {
    const files = Array.from(e.target.files || []);
    if (files.length === 0) return;
    setUploading(true); setErr('');
    try {
      const next = [...f.imagenes];
      for (const file of files) {
        const dataBase64 = await new Promise((resolve, reject) => {
          const r = new FileReader();
          r.onload = () => {
            const s = String(r.result || '');
            resolve(s.includes(',') ? s.split(',')[1] : s);
          };
          r.onerror = () => reject(r.error);
          r.readAsDataURL(file);
        });
        const { data, error } = await supa.functions.invoke('admin-equipos', {
          body: { action: 'upload-image', filename: file.name, contentType: file.type || 'image/jpeg', dataBase64 },
        });
        if (error) throw new Error(error.message || 'fallo al subir');
        if (data && data.error) throw new Error(data.error);
        next.push({ url: data.publicUrl });
      }
      upd('imagenes', next);
      e.target.value = '';
    } catch (err) {
      setErr('Error subiendo imagen: ' + (err.message || err));
    } finally {
      setUploading(false);
    }
  };
  const rmGalleryImg = async (i) => {
    const img = f.imagenes[i];
    if (img && img.url) {
      const path = img.url.split('/equipos/')[1];
      if (path) {
        await supa.functions.invoke('admin-equipos', { body: { action: 'delete-image', path } });
      }
    }
    upd('imagenes', f.imagenes.filter((_, j) => j !== i));
  };
  const moveGallery = (i, dir) => {
    const j = i + dir;
    if (j < 0 || j >= f.imagenes.length) return;
    const next = [...f.imagenes];
    [next[i], next[j]] = [next[j], next[i]];
    upd('imagenes', next);
  };

  const addDesc = () => upd('descripciones_extra', [...f.descripciones_extra, { titulo: '', contenido: '' }]);
  const updDesc = (i, k, v) => {
    const next = [...f.descripciones_extra];
    next[i] = { ...next[i], [k]: v };
    upd('descripciones_extra', next);
  };
  const rmDesc = (i) => upd('descripciones_extra', f.descripciones_extra.filter((_, j) => j !== i));
  const moveDesc = (i, dir) => {
    const j = i + dir;
    if (j < 0 || j >= f.descripciones_extra.length) return;
    const next = [...f.descripciones_extra];
    [next[i], next[j]] = [next[j], next[i]];
    upd('descripciones_extra', next);
  };

  const addSpec = () => upd('especificaciones', [...f.especificaciones, { k: '', v: '' }]);
  const updSpec = (i, k, v) => {
    const next = [...f.especificaciones];
    next[i] = { ...next[i], [k]: v };
    upd('especificaciones', next);
  };
  const rmSpec = (i) => upd('especificaciones', f.especificaciones.filter((_, j) => j !== i));

  const save = async (e) => {
    e.preventDefault();
    setSaving(true); setErr('');
    const cleanSpecs = f.especificaciones.filter(s => s && (s.k || s.v));
    const cleanDescs = f.descripciones_extra.filter(d => d && (d.titulo || d.contenido));
    const cleanImgs = f.imagenes.filter(g => g && g.url);
    const payload = { ...f, especificaciones: cleanSpecs, descripciones_extra: cleanDescs, imagenes: cleanImgs, orden: Number(f.orden) || 0 };
    // Vía Edge Function para bypasear la RLS estricta de equipos.
    const { data, error } = await supa.functions.invoke('admin-equipos', {
      body: isNew
        ? { action: 'create', equipo: payload }
        : { action: 'update', id: equipo.id, equipo: payload },
    });
    if (error) { setErr('Error guardando: ' + (error.message || error)); setSaving(false); return; }
    if (data && data.error) { setErr('Error guardando: ' + data.error); setSaving(false); return; }
    onSaved();
  };

  return (
    <div className="adm-modal" onClick={onClose}>
      <div className="adm-modal-card" onClick={e => e.stopPropagation()}>
        <header className="adm-modal-header">
          <h3>{isNew ? 'Nuevo equipo' : `Editar: ${equipo.nombre}`}</h3>
          <button className="adm-modal-close" onClick={onClose}>×</button>
        </header>
        <form onSubmit={save} className="adm-form">
          <label>Categoría
            <select value={f.categoria} onChange={e=>upd('categoria', e.target.value)}>
              <option value="producto">Producto</option>
              <option value="servicio">Servicio</option>
            </select>
          </label>
          <label>Tipo
            <select value={f.tipo} onChange={e=>upd('tipo', e.target.value)}>
              <option value="">Seleccionar…</option>
              <option>Vulcanizador</option>
              <option>Complementario</option>
              <option>Inspección</option>
              <option>Mantenimiento</option>
              <option>Otro</option>
            </select>
          </label>
          <label className="full">Nombre
            <input required value={f.nombre} onChange={e=>upd('nombre', e.target.value)} />
          </label>
          <label className="full">Ancho de correa máximo (solo productos)
            <input value={f.ancho_correa_max} onChange={e=>upd('ancho_correa_max', e.target.value)} placeholder='Hasta 72"' />
          </label>
          <label className="full">Descripción corta
            <input value={f.descripcion_corta} onChange={e=>upd('descripcion_corta', e.target.value)} maxLength={120} />
          </label>
          <label className="full">Descripción larga
            <textarea rows="4" value={f.descripcion_larga} onChange={e=>upd('descripcion_larga', e.target.value)} />
          </label>

          <div className="full">
            <div className="adm-label">Imagen del equipo</div>
            <div className="adm-img-row">
              {f.imagen_url
                ? <img src={f.imagen_url} alt="preview" className="adm-img-preview" />
                : <div className="adm-img-empty">Sin imagen</div>}
              <div className="adm-img-actions">
                <input type="file" accept="image/*" onChange={upload} disabled={uploading} />
                {uploading && <p className="adm-mute">Subiendo…</p>}
                {f.imagen_url && <button type="button" className="adm-btn danger sm" onClick={removeImg}>Quitar imagen</button>}
              </div>
            </div>
          </div>

          <div className="full">
            <div className="adm-label">Galería de imágenes adicionales</div>
            {f.imagenes.length === 0 && <p className="adm-mute">Sin imágenes adicionales. Use el botón para subir una o más.</p>}
            {f.imagenes.length > 0 && (
              <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(140px, 1fr))', gap:12, marginBottom:12}}>
                {f.imagenes.map((img, i) => (
                  <div key={i} style={{position:'relative', border:'1px solid rgba(255,255,255,.1)', background:'rgba(255,255,255,.04)', borderRadius:8, overflow:'hidden'}}>
                    <img src={img.url} alt="" style={{display:'block', width:'100%', height:110, objectFit:'cover'}} />
                    <div style={{display:'flex', gap:4, padding:6, justifyContent:'space-between', alignItems:'center'}}>
                      <div style={{display:'flex', gap:4}}>
                        <button type="button" className="adm-btn-icon" style={{width:28, height:28, fontSize:14}} onClick={()=>moveGallery(i,-1)} disabled={i===0} aria-label="Subir">↑</button>
                        <button type="button" className="adm-btn-icon" style={{width:28, height:28, fontSize:14}} onClick={()=>moveGallery(i, 1)} disabled={i===f.imagenes.length-1} aria-label="Bajar">↓</button>
                      </div>
                      <button type="button" className="adm-btn-icon" style={{width:28, height:28, fontSize:16}} onClick={()=>rmGalleryImg(i)} aria-label="Eliminar">×</button>
                    </div>
                  </div>
                ))}
              </div>
            )}
            <input type="file" accept="image/*" multiple onChange={uploadGallery} disabled={uploading} />
            {uploading && <p className="adm-mute">Subiendo…</p>}
          </div>

          <div className="full">
            <div className="adm-label">Bloques de descripción adicionales</div>
            {f.descripciones_extra.length === 0 && <p className="adm-mute">Sin bloques. Use el botón para agregar secciones con título y contenido.</p>}
            {f.descripciones_extra.map((d, i) => (
              <div key={i} style={{border:'1px solid rgba(255,255,255,.1)', padding:12, marginBottom:10, background:'rgba(255,255,255,.04)', borderRadius:8}}>
                <div style={{display:'flex', gap:8, alignItems:'center', marginBottom:8}}>
                  <input style={{flex:1}} placeholder="Título del bloque (ej. Aplicaciones)" value={d.titulo || ''} onChange={e=>updDesc(i, 'titulo', e.target.value)} />
                  <button type="button" className="adm-btn-icon" onClick={()=>moveDesc(i,-1)} disabled={i===0}>↑</button>
                  <button type="button" className="adm-btn-icon" onClick={()=>moveDesc(i, 1)} disabled={i===f.descripciones_extra.length-1}>↓</button>
                  <button type="button" className="adm-btn-icon" onClick={()=>rmDesc(i)} aria-label="Eliminar">×</button>
                </div>
                <textarea rows="4" style={{width:'100%'}} placeholder="Contenido del bloque…" value={d.contenido || ''} onChange={e=>updDesc(i, 'contenido', e.target.value)} />
              </div>
            ))}
            <button type="button" className="adm-btn ghost sm" onClick={addDesc}>+ Agregar bloque</button>
          </div>

          <div className="full">
            <div className="adm-label">Especificaciones técnicas</div>
            {f.especificaciones.length === 0 && <p className="adm-mute">Sin especificaciones. Use el botón para agregar.</p>}
            {f.especificaciones.map((s, i) => (
              <div key={i} className="adm-spec-row">
                <input placeholder="Etiqueta (ej. Tipo)" value={s.k || ''} onChange={e=>updSpec(i, 'k', e.target.value)} />
                <input placeholder="Valor (ej. Prensa vulcanizadora)" value={s.v || ''} onChange={e=>updSpec(i, 'v', e.target.value)} />
                <button type="button" className="adm-btn-icon" onClick={()=>rmSpec(i)} aria-label="Eliminar">×</button>
              </div>
            ))}
            <button type="button" className="adm-btn ghost sm" onClick={addSpec}>+ Agregar especificación</button>
          </div>

          <label className="adm-check">
            <input type="checkbox" checked={f.destacado} onChange={e=>upd('destacado', e.target.checked)} />
            Destacado en la home
          </label>
          <label className="adm-check">
            <input type="checkbox" checked={f.disponible} onChange={e=>upd('disponible', e.target.checked)} />
            Disponible para arriendo
          </label>
          <label>Orden
            <input type="number" value={f.orden} onChange={e=>upd('orden', e.target.value)} />
          </label>

          {err && <div className="adm-err full">{err}</div>}

          <div className="adm-form-actions full">
            <button type="button" className="adm-btn ghost" onClick={onClose}>Cancelar</button>
            <button type="submit" className="adm-btn primary" disabled={saving || uploading}>
              {saving ? 'Guardando…' : (isNew ? 'Crear equipo' : 'Guardar cambios')}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}

// ============================================================
// SOLICITUDES (inbox de leads del formulario)
// ============================================================
const ESTADOS = [
  { v: 'nuevo',       l: 'Nuevo',       cls: 'nuevo' },
  { v: 'en_proceso',  l: 'En proceso',  cls: 'proc' },
  { v: 'ganado',      l: 'Ganado',      cls: 'ok' },
  { v: 'perdido',     l: 'Perdido',     cls: 'bad' },
  { v: 'cerrado',     l: 'Cerrado',     cls: 'mute' },
];
const TIPOS_LABELS = {
  servicios:   'Cotización de servicios',
  arriendo:    'Cotización de arriendo',
  general:     'Contacto general',
  corporativo: 'Contacto corporativo',
};

function SolicitudesSection() {
  const supa = window.supabaseClient;
  const [items, setItems] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [filtroTipo, setFiltroTipo] = React.useState('all');
  const [filtroEstado, setFiltroEstado] = React.useState('all');
  const [open, setOpen] = React.useState(null);

  const load = async () => {
    setLoading(true);
    const { data, error } = await supa.functions.invoke('admin-solicitudes', {
      body: { action: 'list' },
    });
    if (error) console.error('admin-solicitudes list', error);
    setItems((data && data.data) || []);
    setLoading(false);
  };
  React.useEffect(() => { load(); }, []);
  React.useEffect(() => { window.lucide && window.lucide.createIcons(); }, [items, open]);

  const visible = items.filter(s =>
    (filtroTipo === 'all' || s.tipo === filtroTipo) &&
    (filtroEstado === 'all' || s.estado === filtroEstado)
  );

  const fmtDate = (iso) => {
    const d = new Date(iso);
    return d.toLocaleDateString('es-CL', { day: '2-digit', month: 'short', year: 'numeric' }) +
           ' · ' + d.toLocaleTimeString('es-CL', { hour: '2-digit', minute: '2-digit' });
  };

  return (
    <>
      <main className="adm-main">
        <div className="adm-toolbar">
          <div>
            <h2>Solicitudes</h2>
            <p className="adm-sub">{items.length} totales · {items.filter(i=>i.estado==='nuevo').length} nuevas sin atender</p>
          </div>
          <button className="adm-btn ghost" onClick={load}><i data-lucide="refresh-cw"></i> Refrescar</button>
        </div>

        <div className="adm-filters">
          <div className="adm-filter-group">
            <span className="adm-filter-label">Tipo</span>
            <select value={filtroTipo} onChange={e=>setFiltroTipo(e.target.value)}>
              <option value="all">Todos</option>
              {Object.entries(TIPOS_LABELS).map(([k,l]) => <option key={k} value={k}>{l}</option>)}
            </select>
          </div>
          <div className="adm-filter-group">
            <span className="adm-filter-label">Estado</span>
            <select value={filtroEstado} onChange={e=>setFiltroEstado(e.target.value)}>
              <option value="all">Todos</option>
              {ESTADOS.map(e => <option key={e.v} value={e.v}>{e.l}</option>)}
            </select>
          </div>
        </div>

        {loading ? (
          <div className="adm-loading">Cargando solicitudes…</div>
        ) : visible.length === 0 ? (
          <div className="adm-empty">
            <p>No hay solicitudes con los filtros actuales.</p>
          </div>
        ) : (
          <div className="adm-table-wrap">
            <table className="adm-table">
              <thead>
                <tr>
                  <th>Estado</th>
                  <th>Tipo</th>
                  <th>Nombre</th>
                  <th>Empresa</th>
                  <th>Contacto</th>
                  <th>Fecha</th>
                  <th></th>
                </tr>
              </thead>
              <tbody>
                {visible.map(s => {
                  const est = ESTADOS.find(e => e.v === s.estado) || ESTADOS[0];
                  return (
                    <tr key={s.id} onClick={()=>setOpen(s)}>
                      <td><span className={`adm-est ${est.cls}`}>{est.l}</span></td>
                      <td><span className="adm-mute">{TIPOS_LABELS[s.tipo] || s.tipo}</span></td>
                      <td>{s.nombre}</td>
                      <td>{s.empresa || '—'}</td>
                      <td className="adm-mute" style={{fontSize:12}}>
                        {s.email && <div>{s.email}</div>}
                        {s.telefono && <div>{s.telefono}</div>}
                      </td>
                      <td className="adm-mute" style={{fontSize:12}}>{fmtDate(s.created_at)}</td>
                      <td><i data-lucide="chevron-right"></i></td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}
      </main>
      {open && <SolicitudModal s={open} onClose={()=>setOpen(null)} onSaved={()=>{ setOpen(null); load(); }} />}
    </>
  );
}

function SolicitudModal({ s, onClose, onSaved }) {
  const supa = window.supabaseClient;
  const [estado, setEstado] = React.useState(s.estado);
  const [notas, setNotas] = React.useState(s.notas_internas || '');
  const [saving, setSaving] = React.useState(false);
  const [err, setErr] = React.useState('');

  React.useEffect(() => { window.lucide && window.lucide.createIcons(); }, []);

  const save = async () => {
    setSaving(true); setErr('');
    const { data, error } = await supa.functions.invoke('admin-solicitudes', {
      body: { action: 'update', id: s.id, estado, notas_internas: notas },
    });
    if (error) { setErr(error.message || 'Error al guardar'); setSaving(false); return; }
    if (data && data.error) { setErr(data.error); setSaving(false); return; }
    onSaved();
  };

  const onDelete = async () => {
    if (!confirm('¿Eliminar esta solicitud?')) return;
    setSaving(true);
    await supa.functions.invoke('admin-solicitudes', {
      body: { action: 'delete', id: s.id },
    });
    onSaved();
  };

  // Construir mensaje + URL para reabrir en WhatsApp
  const lines = [
    `*Solicitud — ${TIPOS_LABELS[s.tipo] || s.tipo}*`,
    `Nombre: ${s.nombre || '-'}`,
    `Empresa: ${s.empresa || '-'}`,
    `Email: ${s.email || '-'}`,
    `Teléfono: ${s.telefono || '-'}`,
  ];
  if (s.servicio)     lines.push(`Servicio: ${s.servicio}`);
  if (s.tipo_equipo)  lines.push(`Tipo de equipo: ${s.tipo_equipo}`);
  if (s.ancho_correa) lines.push(`Ancho de correa: ${s.ancho_correa}`);
  if (s.mensaje)      lines.push('', 'Mensaje:', s.mensaje);
  const waText = lines.join('\n');
  const waUrl = s.telefono
    ? `https://wa.me/${String(s.telefono).replace(/\D/g,'')}?text=${encodeURIComponent(waText)}`
    : null;

  return (
    <div className="adm-modal" onClick={onClose}>
      <div className="adm-modal-card" onClick={e => e.stopPropagation()} style={{maxWidth: 640}}>
        <header className="adm-modal-header">
          <h3>{s.nombre} <span className="adm-mute" style={{fontSize:13, fontWeight:400}}>· {TIPOS_LABELS[s.tipo] || s.tipo}</span></h3>
          <button className="adm-modal-close" onClick={onClose}>×</button>
        </header>
        <div className="adm-sol-body">
          <div className="adm-sol-grid">
            <div><span className="adm-sol-k">Empresa</span><span className="adm-sol-v">{s.empresa || '—'}</span></div>
            <div><span className="adm-sol-k">Email</span><span className="adm-sol-v">{s.email || '—'}</span></div>
            <div><span className="adm-sol-k">Teléfono</span><span className="adm-sol-v">{s.telefono || '—'}</span></div>
            {s.servicio && <div><span className="adm-sol-k">Servicio</span><span className="adm-sol-v">{s.servicio}</span></div>}
            {s.tipo_equipo && <div><span className="adm-sol-k">Tipo de equipo</span><span className="adm-sol-v">{s.tipo_equipo}</span></div>}
            {s.ancho_correa && <div><span className="adm-sol-k">Ancho de correa</span><span className="adm-sol-v">{s.ancho_correa}</span></div>}
          </div>
          {s.mensaje && (
            <div className="adm-sol-msg">
              <span className="adm-sol-k">Mensaje</span>
              <p>{s.mensaje}</p>
            </div>
          )}
          <div className="adm-sol-grid two">
            <label>Estado
              <select value={estado} onChange={e=>setEstado(e.target.value)}>
                {ESTADOS.map(e => <option key={e.v} value={e.v}>{e.l}</option>)}
              </select>
            </label>
            <label>Notas internas
              <textarea rows="3" value={notas} onChange={e=>setNotas(e.target.value)} placeholder="Notas para el equipo (no visibles al cliente)" />
            </label>
          </div>
          {err && <div className="adm-err">{err}</div>}
          <div className="adm-form-actions">
            <button type="button" className="adm-btn danger" onClick={onDelete} disabled={saving}><i data-lucide="trash-2"></i> Eliminar</button>
            <div style={{flex:1}}></div>
            {waUrl && <a className="adm-btn ghost" href={waUrl} target="_blank" rel="noopener noreferrer"><i data-lucide="message-circle"></i> Abrir en WhatsApp</a>}
            <button type="button" className="adm-btn primary" onClick={save} disabled={saving}>{saving ? 'Guardando…' : 'Guardar'}</button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// CONFIGURACIÓN (números de WhatsApp)
// ============================================================
const CONFIG_FIELDS = [
  { key: 'wa_servicios',   label: 'WhatsApp · Servicios',         type: 'phone',   group: 'wa' },
  { key: 'wa_arriendo',    label: 'WhatsApp · Arriendo',          type: 'phone',   group: 'wa' },
  { key: 'wa_general',     label: 'WhatsApp · General',           type: 'phone',   group: 'wa' },
  { key: 'wa_corporativo', label: 'WhatsApp · Corporativo',       type: 'phone',   group: 'wa' },
  { key: 'wa_fab',         label: 'WhatsApp · Botón flotante',    type: 'phone',   group: 'wa' },
  { key: 'wa_fab_message', label: 'Mensaje del botón WhatsApp',   type: 'text',    group: 'wa' },
  { key: 'email_to',       label: 'Email · Destinatario',         type: 'email',   group: 'email' },
  { key: 'email_subject',  label: 'Email · Asunto pre-llenado',   type: 'phone',   group: 'email' },
  { key: 'email_body',     label: 'Email · Cuerpo pre-llenado',   type: 'text',    group: 'email' },
];

function ConfigSection() {
  const supa = window.supabaseClient;
  const [vals, setVals] = React.useState({});
  const [loading, setLoading] = React.useState(true);
  const [saving, setSaving] = React.useState(false);
  const [msg, setMsg] = React.useState('');
  const [err, setErr] = React.useState('');

  const load = async () => {
    setLoading(true);
    const { data: cfg } = await supa.from('config').select('key, value');
    const m = {};
    (cfg || []).forEach(r => { m[r.key] = r.value || ''; });
    setVals(m);
    setLoading(false);
  };
  React.useEffect(() => { load(); }, []);

  const upd = (k, v) => setVals(s => ({ ...s, [k]: v }));

  const save = async (e) => {
    e.preventDefault();
    setSaving(true); setErr(''); setMsg('');
    const rows = CONFIG_FIELDS.map(f => ({ key: f.key, value: vals[f.key] || '' }));
    // El upsert directo a la tabla `config` choca contra RLS en producción
    // (Phase 3 de la migración). Llamamos a la Edge Function `save-config`
    // que está autenticada por JWT y usa el service role para escribir.
    const { data, error } = await supa.functions.invoke('save-config', {
      body: { rows },
    });
    if (error) {
      setErr(error.message || 'Error al guardar la configuración');
      setSaving(false);
      return;
    }
    if (data && data.error) {
      setErr(data.error);
      setSaving(false);
      return;
    }
    if (window.invalidateWaConfig) window.invalidateWaConfig();
    setMsg('Configuración guardada. Los cambios aplicarán al recargar el sitio.');
    setSaving(false);
    setTimeout(() => setMsg(''), 4000);
  };

  return (
    <main className="adm-main">
      <div className="adm-toolbar">
        <div>
          <h2>Configuración</h2>
          <p className="adm-sub">Números de WhatsApp y mensaje del botón flotante. Formato: <code>56912345678</code> (sin espacios ni signos).</p>
        </div>
      </div>

      {loading ? (
        <div className="adm-loading">Cargando…</div>
      ) : (
        <form onSubmit={save} className="adm-config-form">
          <h3 className="adm-config-group">WhatsApp</h3>
          {CONFIG_FIELDS.filter(f => f.group === 'wa').map(f => (
            <label key={f.key} className={f.type === 'text' ? 'full' : ''}>
              <span>{f.label}</span>
              {f.type === 'text'
                ? <textarea rows="2" value={vals[f.key] || ''} onChange={e=>upd(f.key, e.target.value)} />
                : <input type="text" value={vals[f.key] || ''} onChange={e=>upd(f.key, e.target.value)} placeholder="56912345678" />}
            </label>
          ))}
          <h3 className="adm-config-group full">Email</h3>
          <p className="adm-config-help full">
            En <strong>Email · Destinatario</strong> puedes poner cualquier dirección, incluso varias separadas por coma o punto y coma
            (ej. <code>contacto@pertec.cl, alex@pertec.cl, jefe@minera.cl</code>).
          </p>
          {CONFIG_FIELDS.filter(f => f.group === 'email').map(f => (
            <label key={f.key} className={f.type === 'text' ? 'full' : ''}>
              <span>{f.label}</span>
              {f.type === 'text'
                ? <textarea rows="3" value={vals[f.key] || ''} onChange={e=>upd(f.key, e.target.value)} />
                : <input
                    type="text"
                    value={vals[f.key] || ''}
                    onChange={e=>upd(f.key, e.target.value)}
                    placeholder={f.key === 'email_to' ? 'destino@cualquier-empresa.cl' : ''}
                  />}
            </label>
          ))}
          {err && <div className="adm-err full">{err}</div>}
          {msg && <div className="adm-msg full">{msg}</div>}
          <div className="adm-form-actions full">
            <button type="submit" className="adm-btn primary" disabled={saving}>{saving ? 'Guardando…' : 'Guardar configuración'}</button>
          </div>
        </form>
      )}
    </main>
  );
}

// ============================================================
// SECCIÓN CASOS — CRUD de casos publicables (gestionable desde /admin)
// ============================================================
const CASO_COLORES = [
  { v: 'cobre',         label: 'Cobre · negro',     css: 'linear-gradient(135deg,#7a3010,#171411)' },
  { v: 'teal',          label: 'Teal · negro',      css: 'linear-gradient(135deg,#00594a,#171411)' },
  { v: 'cobre-bright',  label: 'Cobre brillante',   css: 'linear-gradient(135deg,#C85217,#2b2927)' },
  { v: 'negro',         label: 'Negro suave',       css: 'linear-gradient(135deg,#3f3c39,#171411)' },
  { v: 'teal-deep',     label: 'Teal profundo',     css: 'linear-gradient(135deg,#004d3e,#171411)' },
];

function colorCss(v) {
  return (CASO_COLORES.find(c => c.v === v) || CASO_COLORES[0]).css;
}

function CasosSection() {
  const supa = window.supabaseClient;
  const [items, setItems] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [editing, setEditing] = React.useState(null);

  const load = async () => {
    setLoading(true);
    const { data, error } = await supa.functions.invoke('admin-casos', { body: { action: 'list' } });
    if (error) console.error('admin-casos list', error);
    setItems((data && data.data) || []);
    setLoading(false);
  };
  React.useEffect(() => { load(); }, []);
  React.useEffect(() => { window.lucide && window.lucide.createIcons(); }, [items, editing]);

  const onDelete = async (c) => {
    if (!confirm(`¿Eliminar "${c.titulo}"?`)) return;
    if (c.imagen_url) {
      const path = c.imagen_url.split('/casos/')[1];
      if (path) await supa.functions.invoke('admin-casos', { body: { action: 'delete-image', path } });
    }
    await supa.functions.invoke('admin-casos', { body: { action: 'delete', id: c.id } });
    load();
  };

  return (
    <main className="adm-main">
      <div className="adm-toolbar">
        <div>
          <h2>Casos</h2>
          <p className="adm-sub">{items.length} casos en total · {items.filter(c => c.visible_en_home).length} visibles en home</p>
        </div>
        <button className="adm-btn primary" onClick={() => setEditing({})}>
          <i data-lucide="plus"></i> Nuevo caso
        </button>
      </div>

      {loading ? (
        <div className="adm-loading">Cargando casos…</div>
      ) : items.length === 0 ? (
        <div className="adm-empty">
          <p>No hay casos cargados todavía.</p>
          <button className="adm-btn primary" onClick={() => setEditing({})}>Agregar el primero</button>
        </div>
      ) : (
        <div className="adm-grid">
          {items.map(c => (
            <article key={c.id} className="adm-card">
              <div className="adm-card-img" style={{ background: colorCss(c.color), aspectRatio: '4/3', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                {c.imagen_url
                  ? <img src={c.imagen_url} alt={c.titulo} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
                  : <span style={{ color: 'rgba(255,255,255,.6)', fontSize: 11, letterSpacing: '.18em', textTransform: 'uppercase' }}>{c.tag || 'Caso'}</span>}
              </div>
              <div className="adm-card-body">
                <h3>{c.titulo}</h3>
                <p className="adm-sub" style={{ fontSize: 12 }}>{c.cliente || '—'} · {c.ano || '—'}</p>
                <p style={{ fontSize: 12, color: 'rgba(255,255,255,.55)', margin: '6px 0 0' }}>{c.metricas || ''}</p>
                <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginTop: 10 }}>
                  {c.destacado && <span className="adm-tag" style={{ background: 'rgba(230,126,63,.18)', color: 'var(--pt-copper-light)' }}>Destacado</span>}
                  {c.visible_en_home && <span className="adm-tag" style={{ background: 'rgba(0,160,128,.18)', color: '#33b399' }}>En home</span>}
                </div>
                <div className="adm-card-actions">
                  <button className="adm-btn ghost sm" onClick={() => setEditing(c)}><i data-lucide="pencil"></i> Editar</button>
                  <button className="adm-btn ghost sm danger" onClick={() => onDelete(c)}><i data-lucide="trash-2"></i></button>
                </div>
              </div>
            </article>
          ))}
        </div>
      )}

      {editing && (
        <CasoForm
          caso={editing}
          onClose={() => setEditing(null)}
          onSaved={() => { setEditing(null); load(); }}
        />
      )}
    </main>
  );
}

function CasoForm({ caso, onClose, onSaved }) {
  const supa = window.supabaseClient;
  const isNew = !caso.id;
  const [f, setF] = React.useState({
    titulo:          caso.titulo          || '',
    cliente:         caso.cliente         || '',
    ano:             caso.ano             || '',
    metricas:        caso.metricas        || '',
    tag:             caso.tag             || '',
    color:           caso.color           || 'cobre',
    imagen_url:      caso.imagen_url      || '',
    orden:           caso.orden           ?? 0,
    destacado:       !!caso.destacado,
    visible_en_home: caso.visible_en_home !== false,
  });
  const [saving, setSaving] = React.useState(false);
  const [uploading, setUploading] = React.useState(false);
  const [err, setErr] = React.useState('');

  React.useEffect(() => { window.lucide && window.lucide.createIcons(); }, []);
  const upd = (k, v) => setF(s => ({ ...s, [k]: v }));

  const upload = async (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setUploading(true); setErr('');
    try {
      const dataBase64 = await new Promise((resolve, reject) => {
        const r = new FileReader();
        r.onload = () => {
          const s = String(r.result || '');
          resolve(s.includes(',') ? s.split(',')[1] : s);
        };
        r.onerror = () => reject(r.error);
        r.readAsDataURL(file);
      });
      const { data, error } = await supa.functions.invoke('admin-casos', {
        body: {
          action: 'upload-image',
          filename: file.name,
          contentType: file.type || 'image/jpeg',
          dataBase64,
        },
      });
      if (error) throw new Error(error.message || 'fallo al subir');
      if (data && data.error) throw new Error(data.error);
      upd('imagen_url', data.publicUrl);
    } catch (err) {
      setErr('Error subiendo imagen: ' + (err.message || err));
    } finally {
      setUploading(false);
    }
  };

  const removeImg = async () => {
    if (!f.imagen_url) return;
    const path = f.imagen_url.split('/casos/')[1];
    if (path) {
      await supa.functions.invoke('admin-casos', { body: { action: 'delete-image', path } });
    }
    upd('imagen_url', '');
  };

  const save = async (e) => {
    e.preventDefault();
    if (!f.titulo.trim()) { setErr('El título es obligatorio.'); return; }
    setSaving(true); setErr('');
    const payload = { ...f, orden: Number(f.orden) || 0 };
    const { data, error } = await supa.functions.invoke('admin-casos', {
      body: isNew
        ? { action: 'create', caso: payload }
        : { action: 'update', id: caso.id, caso: payload },
    });
    if (error) { setErr('Error guardando: ' + (error.message || error)); setSaving(false); return; }
    if (data && data.error) { setErr('Error guardando: ' + data.error); setSaving(false); return; }
    onSaved();
  };

  return (
    <div className="adm-modal" onClick={onClose}>
      <div className="adm-modal-inner" onClick={e => e.stopPropagation()}>
        <div className="adm-modal-head">
          <h3>{isNew ? 'Nuevo caso' : 'Editar caso'}</h3>
          <button className="adm-modal-close" onClick={onClose} aria-label="Cerrar">×</button>
        </div>
        <form onSubmit={save} className="adm-form">
          <label>
            <span>Título</span>
            <input value={f.titulo} onChange={e => upd('titulo', e.target.value)} placeholder="Cambio de correa overland" required />
          </label>
          <label>
            <span>Cliente / faena</span>
            <input value={f.cliente} onChange={e => upd('cliente', e.target.value)} placeholder="Los Bronces" />
          </label>
          <label>
            <span>Año</span>
            <input value={f.ano} onChange={e => upd('ano', e.target.value)} placeholder="2024 o Continuo" />
          </label>
          <label>
            <span>Métricas</span>
            <input value={f.metricas} onChange={e => upd('metricas', e.target.value)} placeholder='72" · 2.4 km' />
          </label>
          <label>
            <span>Tag</span>
            <input value={f.tag} onChange={e => upd('tag', e.target.value)} placeholder="Overland conveyor" />
          </label>
          <label>
            <span>Color del fondo</span>
            <select value={f.color} onChange={e => upd('color', e.target.value)}>
              {CASO_COLORES.map(c => <option key={c.v} value={c.v}>{c.label}</option>)}
            </select>
          </label>
          <label>
            <span>Orden (menor primero)</span>
            <input type="number" value={f.orden} onChange={e => upd('orden', e.target.value)} />
          </label>
          <label className="full" style={{ flexDirection: 'row', alignItems: 'center', gap: 10 }}>
            <input type="checkbox" checked={f.destacado} onChange={e => upd('destacado', e.target.checked)} />
            <span>Marcar como destacado</span>
          </label>
          <label className="full" style={{ flexDirection: 'row', alignItems: 'center', gap: 10 }}>
            <input type="checkbox" checked={f.visible_en_home} onChange={e => upd('visible_en_home', e.target.checked)} />
            <span>Visible en home (sección de la portada)</span>
          </label>

          <div className="full">
            <span style={{ display: 'block', fontSize: 11, letterSpacing: '.14em', textTransform: 'uppercase', color: 'rgba(255,255,255,.6)', marginBottom: 8 }}>Imagen (opcional)</span>
            {f.imagen_url ? (
              <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start' }}>
                <img src={f.imagen_url} alt="" style={{ width: 120, height: 90, objectFit: 'cover', border: '1px solid rgba(255,255,255,.1)' }} />
                <button type="button" className="adm-btn ghost sm danger" onClick={removeImg}>
                  <i data-lucide="trash-2"></i> Quitar imagen
                </button>
              </div>
            ) : (
              <input type="file" accept="image/*" onChange={upload} disabled={uploading} />
            )}
            {uploading && <p style={{ fontSize: 12, color: 'rgba(255,255,255,.55)', marginTop: 6 }}>Subiendo…</p>}
          </div>

          {err && <div className="adm-err full">{err}</div>}

          <div className="adm-form-actions full">
            <button type="button" className="adm-btn ghost" onClick={onClose}>Cancelar</button>
            <button type="submit" className="adm-btn primary" disabled={saving}>
              {saving ? 'Guardando…' : (isNew ? 'Crear caso' : 'Guardar cambios')}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}

window.AdminApp = AdminApp;
