// LOLA Consola Web — Catálogos: Tipos de transporte y Tipos de carga.
// CRUD real contra /admin/catalogos/* — antes esos campos eran texto libre en el formulario
// de Solicitar; ahora el admin controla la lista exacta que ve cliente/proveedor.
// Exporta window.CatalogosView.

const api = () => window.LOLA.api;

function CIco({ children, size = 18, sw = 2, ...p }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
      strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round" {...p}>{children}</svg>
  );
}
// Íconos seleccionables por entrada del catálogo (self-contained: no depende de window.WI).
const CAT_ICONS = {
  Truck:   (p) => <CIco {...p}><path d="M3 7h11v10H3z"/><path d="M14 10h4l3 3v4h-7z"/><circle cx="7" cy="17" r="2"/><circle cx="17" cy="17" r="2"/></CIco>,
  Car:     (p) => <CIco {...p}><path d="M5 11h14l-2-5H7z"/><path d="M3 17v-6h18v6"/><circle cx="7" cy="17" r="2"/><circle cx="17" cy="17" r="2"/></CIco>,
  Package: (p) => <CIco {...p}><path d="M21 8 12 3 3 8v8l9 5 9-5V8z"/><path d="M3 8l9 5 9-5"/><path d="M12 13v8"/></CIco>,
  Weight:  (p) => <CIco {...p}><circle cx="12" cy="8" r="2"/><path d="M9 5a3 3 0 1 1 6 0M5 21l2-11h10l2 11z"/></CIco>,
  Home:    (p) => <CIco {...p}><path d="M3 11 12 3l9 8v10h-6v-6h-6v6H3z"/></CIco>,
  Alert:   (p) => <CIco {...p}><path d="M12 2 2 20h20z"/><path d="M12 9v5M12 17h.01"/></CIco>,
};
const ICON_OPTS = Object.keys(CAT_ICONS);
function CatIcon({ name, size = 18, ...p }) { const C = CAT_ICONS[name] || CAT_ICONS.Package; return <C size={size} {...p}/>; }
// Íconos de acción de la fila (editar/borrar/agregar) — set chico aparte de los seleccionables.
const IPencil = (p) => <CIco {...p}><path d="M17 3a2.85 2.85 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5z"/></CIco>;
const ITrash  = (p) => <CIco {...p}><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2m3 0-1 14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2L4 6"/></CIco>;
const IPlus   = (p) => <CIco {...p}><path d="M12 5v14M5 12h14"/></CIco>;
const IX      = (p) => <CIco {...p}><path d="M18 6 6 18M6 6l12 12"/></CIco>;

const TABS = [
  { id: 'transporte', label: 'Tipos de transporte', sub: 'Lo que el cliente elige como "Tipo de transporte" al solicitar un servicio.', defIcon: 'Truck',
    list: 'tiposTransporte', crear: 'crearTipoTransporte', actualizar: 'actualizarTipoTransporte', borrar: 'borrarTipoTransporte' },
  { id: 'carga', label: 'Tipos de carga', sub: 'Lo que el cliente elige como "Tipo de carga" al solicitar un servicio.', defIcon: 'Package',
    list: 'tiposCarga', crear: 'crearTipoCarga', actualizar: 'actualizarTipoCarga', borrar: 'borrarTipoCarga' },
];

// ── Fila: vista normal + modo edición inline (mismo layout, sin modal) ─────────────────────
function ItemRow({ item, editing, onEdit, onCancel, onSave, onToggle, onDelete, busy }) {
  const t = window.WC;
  const [nombre, setNombre] = React.useState(item.nombre);
  const [icono, setIcono] = React.useState(item.icono);
  const [confirmDel, setConfirmDel] = React.useState(false);
  React.useEffect(() => { setNombre(item.nombre); setIcono(item.icono); }, [item.id, editing]);

  if (editing) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '10px 14px', borderBottom: `1px solid ${t.border}`, background: '#FAFBFC', flexWrap: 'wrap' }}>
        <div style={{ display: 'flex', gap: 4, flexShrink: 0 }}>
          {ICON_OPTS.map((ic) => (
            <button key={ic} onClick={() => setIcono(ic)} title={ic} style={{
              width: 30, height: 30, borderRadius: 8, border: `1.5px solid ${icono === ic ? t.brand : t.border}`,
              background: icono === ic ? t.brand + '18' : '#fff', color: icono === ic ? t.brand : t.sec,
              display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer',
            }}><CatIcon name={ic} size={15}/></button>
          ))}
        </div>
        <input autoFocus value={nombre} onChange={(e) => setNombre(e.target.value)}
          onKeyDown={(e) => { if (e.key === 'Enter' && nombre.trim()) onSave(item.id, { nombre: nombre.trim(), icono }); if (e.key === 'Escape') onCancel(); }}
          style={{ flex: 1, minWidth: 160, height: 34, padding: '0 10px', borderRadius: 8, border: `1.5px solid ${t.brand}`, fontFamily: t.font, fontSize: 13.5, outline: 'none' }}/>
        <button disabled={busy || !nombre.trim()} onClick={() => onSave(item.id, { nombre: nombre.trim(), icono })} style={{
          height: 34, padding: '0 14px', borderRadius: 8, border: 'none', background: t.brand, color: '#fff',
          fontWeight: 700, fontSize: 13, cursor: busy ? 'default' : 'pointer', opacity: !nombre.trim() ? .5 : 1, flexShrink: 0 }}>
          Guardar
        </button>
        <button onClick={onCancel} style={{ height: 34, padding: '0 12px', borderRadius: 8, border: `1px solid ${t.border}`, background: '#fff', color: t.sec, fontSize: 13, cursor: 'pointer', flexShrink: 0 }}>Cancelar</button>
      </div>
    );
  }
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '11px 14px', borderBottom: `1px solid ${t.border}`, opacity: item.activo ? 1 : .5 }}>
      <span style={{ width: 34, height: 34, borderRadius: 9, background: t.brand + '12', color: t.brand, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
        <CatIcon name={item.icono}/>
      </span>
      <div style={{ flex: 1, minWidth: 0, fontSize: 14, fontWeight: 600, color: t.text, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{item.nombre}</div>
      {!item.activo && <span style={{ fontSize: 10.5, fontFamily: t.mono, fontWeight: 700, letterSpacing: .6, textTransform: 'uppercase', color: t.ter, background: '#F1F2F4', padding: '3px 8px', borderRadius: 999, flexShrink: 0 }}>Inactivo</span>}
      <label title={item.activo ? 'Visible para cliente/proveedor' : 'Oculto para cliente/proveedor'} style={{ display: 'flex', alignItems: 'center', gap: 6, cursor: busy ? 'default' : 'pointer', flexShrink: 0 }}>
        <input type="checkbox" checked={item.activo} disabled={busy} onChange={() => onToggle(item)} style={{ width: 16, height: 16, cursor: busy ? 'default' : 'pointer', accentColor: t.brand }}/>
      </label>
      {confirmDel ? (
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexShrink: 0 }}>
          <span style={{ fontSize: 12, color: t.ter }}>¿Eliminar?</span>
          <button disabled={busy} onClick={() => onDelete(item.id)} style={{ height: 28, padding: '0 10px', borderRadius: 7, border: 'none', background: t.danger, color: '#fff', fontSize: 12, fontWeight: 700, cursor: 'pointer' }}>Sí</button>
          <button onClick={() => setConfirmDel(false)} style={{ height: 28, padding: '0 10px', borderRadius: 7, border: `1px solid ${t.border}`, background: '#fff', color: t.sec, fontSize: 12, cursor: 'pointer' }}>No</button>
        </div>
      ) : (
        <div style={{ display: 'flex', gap: 6, flexShrink: 0 }}>
          <button onClick={() => onEdit(item.id)} title="Editar" style={{ width: 30, height: 30, borderRadius: 8, border: `1px solid ${t.border}`, background: '#fff', color: t.sec, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><IPencil size={14}/></button>
          <button onClick={() => setConfirmDel(true)} title="Eliminar" style={{ width: 30, height: 30, borderRadius: 8, border: `1px solid ${t.border}`, background: '#fff', color: t.danger, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><ITrash size={14}/></button>
        </div>
      )}
    </div>
  );
}

// ── Panel de una pestaña (transporte o carga) ──────────────────────────────────────────────
function TabPanel({ cfg }) {
  const t = window.WC;
  const [items, setItems] = React.useState(null);
  const [error, setError] = React.useState(null);
  const [busyId, setBusyId] = React.useState(null);
  const [editingId, setEditingId] = React.useState(null);
  const [adding, setAdding] = React.useState(false);

  const cargar = React.useCallback(() => {
    setError(null);
    api()[cfg.list]().then((r) => setItems(r.items || [])).catch(setError);
  }, [cfg.list]);
  React.useEffect(() => { setItems(null); cargar(); setEditingId(null); setAdding(false); }, [cfg.id, cargar]);

  const guardar = async (id, patch) => {
    setBusyId(id);
    try {
      const r = await api()[cfg.actualizar](id, patch);
      setItems((arr) => arr.map((x) => (x.id === id ? r.item : x)));
      setEditingId(null);
    } catch (e) { window.alert(e.message || 'No se pudo guardar.'); }
    finally { setBusyId(null); }
  };
  const toggle = (item) => guardar(item.id, { activo: !item.activo });
  const borrar = async (id) => {
    setBusyId(id);
    try { await api()[cfg.borrar](id); setItems((arr) => arr.filter((x) => x.id !== id)); }
    catch (e) { window.alert(e.message || 'No se pudo eliminar.'); }
    finally { setBusyId(null); }
  };
  const crear = async (nombre, icono) => {
    setBusyId('new');
    try {
      const r = await api()[cfg.crear]({ nombre, icono });
      setItems((arr) => [...(arr || []), r.item]);
      setAdding(false);
    } catch (e) { window.alert(e.message || 'No se pudo crear.'); }
    finally { setBusyId(null); }
  };

  if (error) return <window.ErrState error={error} onRetry={cargar}/>;
  if (!items) return <window.Loading label="Cargando…"/>;
  return (
    <div style={{ background: '#fff', borderRadius: 14, border: `1px solid ${t.border}`, overflow: 'hidden' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '14px 16px', borderBottom: `1px solid ${t.border}` }}>
        <div style={{ fontSize: 13, color: t.ter }}>{items.length} {items.length === 1 ? 'entrada' : 'entradas'} · {items.filter((x) => x.activo).length} activas</div>
        <button onClick={() => { setAdding(true); setEditingId(null); }} style={{
          display: 'flex', alignItems: 'center', gap: 6, height: 34, padding: '0 13px', borderRadius: 8, border: 'none',
          background: t.brand, color: '#fff', fontWeight: 700, fontSize: 13, cursor: 'pointer' }}>
          <IPlus size={15}/> Agregar
        </button>
      </div>
      {adding && (
        <NewRow defIcon={cfg.defIcon} busy={busyId === 'new'} onCancel={() => setAdding(false)} onCrear={crear}/>
      )}
      {items.length === 0 && !adding ? (
        <window.EmptyState icon="Truck" title="Todavía no hay entradas" sub={`Agrega el primer elemento de "${cfg.label}".`}/>
      ) : items.map((item) => (
        <ItemRow key={item.id} item={item} editing={editingId === item.id} busy={busyId === item.id}
          onEdit={setEditingId} onCancel={() => setEditingId(null)} onSave={guardar} onToggle={toggle} onDelete={borrar}/>
      ))}
    </div>
  );
}

function NewRow({ defIcon, busy, onCancel, onCrear }) {
  const t = window.WC;
  const [nombre, setNombre] = React.useState('');
  const [icono, setIcono] = React.useState(defIcon);
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '10px 14px', borderBottom: `1px solid ${t.border}`, background: 'rgba(29,87,169,0.04)', flexWrap: 'wrap' }}>
      <div style={{ display: 'flex', gap: 4, flexShrink: 0 }}>
        {ICON_OPTS.map((ic) => (
          <button key={ic} onClick={() => setIcono(ic)} title={ic} style={{
            width: 30, height: 30, borderRadius: 8, border: `1.5px solid ${icono === ic ? t.brand : t.border}`,
            background: icono === ic ? t.brand + '18' : '#fff', color: icono === ic ? t.brand : t.sec,
            display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }}><CatIcon name={ic} size={15}/></button>
        ))}
      </div>
      <input autoFocus value={nombre} onChange={(e) => setNombre(e.target.value)} placeholder="Nombre, ej. Furgón cerrado"
        onKeyDown={(e) => { if (e.key === 'Enter' && nombre.trim()) onCrear(nombre.trim(), icono); if (e.key === 'Escape') onCancel(); }}
        style={{ flex: 1, minWidth: 160, height: 34, padding: '0 10px', borderRadius: 8, border: `1.5px solid ${t.brand}`, fontFamily: t.font, fontSize: 13.5, outline: 'none' }}/>
      <button disabled={busy || !nombre.trim()} onClick={() => onCrear(nombre.trim(), icono)} style={{
        height: 34, padding: '0 14px', borderRadius: 8, border: 'none', background: t.brand, color: '#fff',
        fontWeight: 700, fontSize: 13, cursor: 'pointer', opacity: !nombre.trim() ? .5 : 1, flexShrink: 0 }}>Crear</button>
      <button onClick={onCancel} style={{ width: 34, height: 34, borderRadius: 8, border: `1px solid ${t.border}`, background: '#fff', color: t.sec, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><IX size={14}/></button>
    </div>
  );
}

window.CatalogosView = function CatalogosView() {
  const t = window.WC;
  const [tab, setTab] = React.useState('transporte');
  const cfg = TABS.find((x) => x.id === tab);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      <div style={{ display: 'flex', gap: 8 }}>
        {TABS.map((x) => (
          <button key={x.id} onClick={() => setTab(x.id)} style={{
            display: 'flex', alignItems: 'center', gap: 8, height: 38, padding: '0 16px', borderRadius: 10,
            border: `1.5px solid ${tab === x.id ? t.brand : t.border}`,
            background: tab === x.id ? t.brand : '#fff', color: tab === x.id ? '#fff' : t.text,
            fontFamily: t.font, fontSize: 13.5, fontWeight: 700, cursor: 'pointer' }}>
            <CatIcon name={x.defIcon} size={16}/> {x.label}
          </button>
        ))}
      </div>
      <div style={{ fontSize: 13, color: t.ter, marginTop: -8 }}>{cfg.sub}</div>
      <TabPanel cfg={cfg}/>
    </div>
  );
};
