// LOLA Consola Web — PASARELAS DE PAGO parametrizables. Configuración → Pasarelas de pago.
// Lee/escribe SIEMPRE contra /admin/pasarelas (credenciales cifradas en Mongo; aquí solo llegan
// enmascaradas). Incluye guía "Cómo configurarla" por proveedor (web/pasarelas-ayuda.js).

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

function PasarelasView() {
  const t = window.WC, I = window.WI;
  const q = window.useAsync(() => pApi().pasarelas(), []);
  const [sel, setSel] = React.useState(null);
  const [ayuda, setAyuda] = React.useState(null); // proveedor | 'general'
  if (q.loading) return <window.Loading/>;
  if (q.error) return <window.ErrState error={q.error} onRetry={q.reload}/>;
  const items = q.data.items || [];
  const grupos = window.PASARELAS_GRUPOS || [];
  const activas = items.filter((p) => p.activa);
  const byProv = Object.fromEntries(items.map((p) => [p.proveedor, p]));

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 18, maxWidth: 1100 }}>
      {/* Estado general */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 12 }}>
        <PStat t={t} label="Pasarelas activas" value={activas.length} sub={activas.length ? activas.map((p) => p.esquema.nombre).join(' · ') : 'Ninguna — solo transferencia manual'} tone={activas.length ? 'ok' : 'warn'}/>
        <PStat t={t} label="Recarga con tarjeta" value={activas.some((p) => p.usos.includes('recarga') && p.proveedor !== 'manual') ? 'Disponible' : 'No disponible'} sub="Lo que ve el transportista en Comprar saldo" tone={activas.some((p) => p.usos.includes('recarga') && p.proveedor !== 'manual') ? 'ok' : 'warn'}/>
        <PStat t={t} label="En producción" value={activas.filter((p) => p.entorno === 'produccion').length} sub={activas.some((p) => p.entorno === 'sandbox') ? 'Hay pasarelas en modo pruebas' : 'Sin pruebas pendientes'} tone="neutral"/>
        <button onClick={() => setAyuda('general')} style={{ textAlign: 'left', cursor: 'pointer', background: t.brand, color: '#fff', border: 'none', borderRadius: 14, padding: '16px 18px', display: 'flex', alignItems: 'center', gap: 12, fontFamily: t.font }}>
          <span style={{ width: 40, height: 40, borderRadius: 11, background: 'rgba(255,255,255,.16)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}><I.Book size={20}/></span>
          <span><b style={{ display: 'block', fontSize: 14.5 }}>¿Cómo funciona esta pantalla?</b><span style={{ fontSize: 12.5, opacity: .85 }}>Guía paso a paso y seguridad</span></span>
        </button>
      </div>

      {grupos.map((g) => (
        <div key={g.k}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginBottom: 10 }}>
            <h3 style={{ margin: 0, fontSize: 16, fontWeight: 800, color: t.text }}>{g.titulo}</h3>
            <span style={{ fontSize: 12.5, color: t.sec }}>{g.sub}</span>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))', gap: 12 }}>
            {g.proveedores.map((prov) => byProv[prov] && <PasarelaCard key={prov} t={t} I={I} p={byProv[prov]} onConfig={() => setSel(prov)} onAyuda={() => setAyuda(prov)}/>)}
          </div>
        </div>
      ))}

      <div style={{ fontSize: 12.5, color: t.ter, lineHeight: 1.5, display: 'flex', gap: 8, alignItems: 'flex-start' }}>
        <I.Shield size={15}/> Las credenciales se cifran con AES-256-GCM antes de guardarse y nunca vuelven completas a esta pantalla. LOLA no almacena números de tarjeta: la captura ocurre en la página segura del proveedor (PCI DSS). Cada cambio queda en Auditoría.
      </div>

      {sel && <PasarelaModal t={t} I={I} p={byProv[sel]} onClose={() => setSel(null)} onSaved={() => { setSel(null); q.reload(); }} onAyuda={() => setAyuda(sel)}/>}
      {ayuda && <AyudaModal t={t} I={I} prov={ayuda} onClose={() => setAyuda(null)} onConfig={ayuda !== 'general' ? () => { setAyuda(null); setSel(ayuda); } : null}/>}
    </div>
  );
}

function PStat({ t, label, value, sub, tone }) {
  const c = tone === 'ok' ? '#1F8A5B' : tone === 'warn' ? '#D98A0B' : t.brand;
  return (
    <div style={{ background: '#fff', border: `1px solid ${t.border}`, borderRadius: 14, padding: '14px 18px' }}>
      <div style={{ fontSize: 11, color: t.ter, fontFamily: t.mono, textTransform: 'uppercase', letterSpacing: .8, fontWeight: 700 }}>{label}</div>
      <div style={{ fontSize: 22, fontWeight: 800, color: c, marginTop: 4, letterSpacing: -.5 }}>{value}</div>
      <div style={{ fontSize: 12.5, color: t.sec, marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{sub}</div>
    </div>
  );
}

function PasarelaCard({ t, I, p, onConfig, onAyuda }) {
  const e = p.esquema;
  const credsOk = (e.credenciales || []).filter((c) => c.req).every((c) => p.credenciales[c.k] && p.credenciales[c.k].definida);
  const estado = p.activa ? ['Activa', '#1F8A5B'] : p.configurada && credsOk ? ['Lista para activar', t.brand] : p.configurada ? ['Incompleta', '#D98A0B'] : ['Sin configurar', t.ter];
  return (
    <div style={{ background: '#fff', border: `1px solid ${p.activa ? '#1F8A5B55' : t.border}`, borderRadius: 16, padding: 18, display: 'flex', flexDirection: 'column', gap: 12, boxShadow: p.activa ? '0 0 0 3px #1F8A5B14' : 'none' }}>
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12 }}>
        <span style={{ width: 42, height: 42, borderRadius: 12, background: p.activa ? '#1F8A5B14' : t.brand + '12', color: p.activa ? '#1F8A5B' : t.brand, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><I.Wallet size={20}/></span>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
            <b style={{ fontSize: 15, color: t.text }}>{e.nombre}</b>
            {e.recomendada && <span style={{ fontSize: 10.5, fontWeight: 800, padding: '2px 8px', borderRadius: 999, background: '#F4C71E', color: '#1A1400', letterSpacing: .4 }}>RECOMENDADA</span>}
          </div>
          <div style={{ fontSize: 12, color: t.ter, marginTop: 2 }}>{e.region}</div>
        </div>
        <span style={{ fontSize: 11.5, fontWeight: 700, color: estado[1], background: estado[1] + '14', padding: '4px 10px', borderRadius: 999, whiteSpace: 'nowrap' }}>{estado[0]}</span>
      </div>
      <div style={{ fontSize: 13, color: t.sec, lineHeight: 1.5 }}>{e.descripcion}</div>
      {p.configurada && (
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
          <span style={pChip(t)}>{p.entorno === 'produccion' ? 'Producción' : 'Sandbox'}</span>
          {p.usos.map((u) => <span key={u} style={pChip(t)}>{({ tarjeta: 'Tarjeta', recarga: 'Recarga', retiro: 'Retiro', tokenizacion: 'Tokenización' })[u] || u}</span>)}
          {p.prueba && p.prueba.at && <span style={{ ...pChip(t), color: p.prueba.ok ? '#1F8A5B' : t.danger }}>Prueba: {p.prueba.ok ? 'OK' : 'falló'}</span>}
        </div>
      )}
      <div style={{ display: 'flex', gap: 8, marginTop: 'auto' }}>
        <button onClick={onConfig} style={{ flex: 1, height: 38, borderRadius: 10, border: 'none', ...window.GOLD, fontWeight: 750, cursor: 'pointer', fontFamily: t.font, fontSize: 13.5 }}>{p.configurada ? 'Editar' : 'Configurar'}</button>
        <button onClick={onAyuda} style={{ height: 38, padding: '0 14px', borderRadius: 10, border: `1px solid ${t.border}`, background: '#fff', color: t.text, fontWeight: 600, cursor: 'pointer', fontFamily: t.font, fontSize: 13.5, display: 'flex', alignItems: 'center', gap: 6 }}><I.Book size={15}/> Cómo configurarla</button>
      </div>
    </div>
  );
}
const pChip = (t) => ({ fontSize: 11.5, fontWeight: 600, color: t.sec, background: t.grid, padding: '3px 9px', borderRadius: 8 });

function PasarelaModal({ t, I, p, onClose, onSaved, onAyuda }) {
  const e = p.esquema;
  const [f, setF] = React.useState({
    nombre: p.nombre || e.nombre, entorno: p.entorno || 'sandbox', activa: !!p.activa, usos: p.usos && p.usos.length ? p.usos : e.usos.slice(0, 2), prioridad: p.prioridad || 10,
    limites: p.limites || { montoMin: 1, montoMax: 100000, comisionPct: 0, comisionFija: 0 }, parametros: Object.assign({}, p.parametros || {}), credenciales: {},
  });
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState('');
  const [prueba, setPrueba] = React.useState(p.prueba || null);
  const [ver, setVer] = React.useState({});
  const inp = { width: '100%', height: 40, padding: '0 12px', borderRadius: 9, border: `1px solid ${t.border}`, fontFamily: t.font, fontSize: 13.5, color: t.text, background: '#fff', outline: 'none', boxSizing: 'border-box' };
  const lbl = { display: 'block', fontSize: 12.5, fontWeight: 700, color: t.text, marginBottom: 6 };
  const guardar = async (activar) => {
    setBusy(true); setErr('');
    try {
      await pApi().guardarPasarela(p.proveedor, { ...f, activa: activar !== undefined ? activar : f.activa });
      onSaved();
    } catch (ex) { setErr(ex.message || 'No se pudo guardar'); }
    setBusy(false);
  };
  const probar = async () => {
    setBusy(true); setErr('');
    try {
      await pApi().guardarPasarela(p.proveedor, { ...f, activa: f.activa });
      const r = await pApi().probarPasarela(p.proveedor);
      setPrueba(r.prueba);
    } catch (ex) { setErr(ex.message || 'No se pudo probar'); }
    setBusy(false);
  };
  const borrar = async () => {
    if (!window.confirm('¿Borrar la configuración y las credenciales de ' + e.nombre + '?')) return;
    setBusy(true);
    try { await pApi().borrarPasarela(p.proveedor); onSaved(); } catch (ex) { setErr(ex.message); setBusy(false); }
  };
  const webhookUrl = location.origin + (p.webhook && p.webhook.url ? p.webhook.url : '/api/v1/pagos/webhook/' + p.proveedor);
  return (
    <window.Modal title={(p.configurada ? 'Editar ' : 'Configurar ') + e.nombre} sub={e.region} width={760} onClose={onClose}
      footer={<div style={{ display: 'flex', gap: 8, width: '100%', alignItems: 'center' }}>
        {p.configurada && <button onClick={borrar} disabled={busy} style={{ ...mBtn(t), color: t.danger, borderColor: '#F2C4C0' }}>Borrar</button>}
        <button onClick={onAyuda} style={{ ...mBtn(t), display: 'flex', alignItems: 'center', gap: 6 }}><I.Book size={15}/> Guía</button>
        <span style={{ flex: 1 }}/>
        <button onClick={probar} disabled={busy} style={mBtn(t)}>{busy ? '…' : 'Probar conexión'}</button>
        <button onClick={() => guardar()} disabled={busy} style={{ ...mBtn(t), ...window.GOLD }}>{busy ? 'Guardando…' : 'Guardar'}</button>
      </div>}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
        {err && <div style={{ padding: '10px 14px', borderRadius: 10, background: '#FDF0EF', border: '1px solid #F2C4C0', color: t.danger, fontSize: 13 }}>{err}</div>}
        {prueba && prueba.at && (
          <div style={{ padding: '10px 14px', borderRadius: 10, background: prueba.ok ? '#EAF7F0' : '#FDF0EF', border: `1px solid ${prueba.ok ? '#A9DFC0' : '#F2C4C0'}`, color: prueba.ok ? '#1F8A5B' : t.danger, fontSize: 13, fontWeight: 600 }}>
            {prueba.ok ? '✓ ' : '✕ '}{prueba.mensaje} <span style={{ color: t.ter, fontWeight: 500 }}>· {new Date(prueba.at).toLocaleString('es-GT')}</span>
          </div>
        )}

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
          <div><label style={lbl}>Nombre visible</label><input style={inp} value={f.nombre} onChange={(ev) => setF({ ...f, nombre: ev.target.value })}/></div>
          <div><label style={lbl}>Entorno</label>
            <div style={{ display: 'flex', background: t.grid, borderRadius: 10, padding: 3 }}>
              {[['sandbox', 'Sandbox (pruebas)'], ['produccion', 'Producción']].map(([k, l]) => (
                <button key={k} onClick={() => setF({ ...f, entorno: k })} style={{ flex: 1, height: 34, borderRadius: 8, border: 'none', cursor: 'pointer', fontFamily: t.font, fontSize: 13, fontWeight: 700, background: f.entorno === k ? '#fff' : 'transparent', color: f.entorno === k ? (k === 'produccion' ? '#1F8A5B' : t.brand) : t.sec, boxShadow: f.entorno === k ? '0 1px 3px rgba(0,0,0,.12)' : 'none' }}>{l}</button>
              ))}
            </div>
          </div>
        </div>

        <div>
          <label style={lbl}>Se usa para</label>
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            {e.usos.map((u) => { const on = f.usos.includes(u); return (
              <button key={u} onClick={() => setF({ ...f, usos: on ? f.usos.filter((x) => x !== u) : [...f.usos, u] })} style={{ height: 34, padding: '0 14px', borderRadius: 999, border: `1px solid ${on ? t.brand : t.border}`, background: on ? t.brand + '12' : '#fff', color: on ? t.brand : t.sec, fontWeight: 700, fontSize: 13, cursor: 'pointer', fontFamily: t.font }}>{({ tarjeta: 'Pago de servicios con tarjeta', recarga: 'Comprar saldo (recarga)', retiro: 'Retiros a banco', tokenizacion: 'Guardar tarjetas (tokens)' })[u] || u}</button>
            ); })}
          </div>
        </div>

        {e.credenciales.length > 0 && (
          <div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}><I.Lock size={15}/><b style={{ fontSize: 14 }}>Credenciales</b><span style={{ fontSize: 12, color: t.ter }}>se cifran al guardar · deja vacío para conservar la actual</span></div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
              {e.credenciales.map((c) => { const cur = p.credenciales[c.k]; return (
                <div key={c.k}>
                  <label style={lbl}>{c.label}{c.req && <span style={{ color: t.danger }}> *</span>}</label>
                  <div style={{ position: 'relative' }}>
                    <input type={ver[c.k] ? 'text' : 'password'} style={{ ...inp, fontFamily: t.mono, paddingRight: 40 }} placeholder={cur && cur.definida ? 'Guardada: ' + cur.mascara : c.ph} value={f.credenciales[c.k] || ''} onChange={(ev) => setF({ ...f, credenciales: { ...f.credenciales, [c.k]: ev.target.value } })} autoComplete="off"/>
                    <button onClick={() => setVer({ ...ver, [c.k]: !ver[c.k] })} title="Mostrar" style={{ position: 'absolute', right: 6, top: 6, width: 28, height: 28, border: 'none', background: 'transparent', cursor: 'pointer', color: t.ter }}><I.Eye size={16}/></button>
                  </div>
                </div>
              ); })}
            </div>
          </div>
        )}

        {e.parametros.length > 0 && (
          <div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}><I.Gear size={15}/><b style={{ fontSize: 14 }}>Parámetros</b></div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
              {e.parametros.map((pm) => (
                <div key={pm.k}>
                  <label style={lbl}>{pm.label}{pm.req && <span style={{ color: t.danger }}> *</span>}</label>
                  {pm.tipo === 'select' ? (
                    <select style={inp} value={f.parametros[pm.k] || ''} onChange={(ev) => setF({ ...f, parametros: { ...f.parametros, [pm.k]: ev.target.value } })}>
                      <option value="">Selecciona…</option>{pm.opciones.map((o) => <option key={o} value={o}>{o}</option>)}
                    </select>
                  ) : <input style={inp} placeholder={pm.ph} value={f.parametros[pm.k] || ''} onChange={(ev) => setF({ ...f, parametros: { ...f.parametros, [pm.k]: ev.target.value } })}/>}
                </div>
              ))}
            </div>
          </div>
        )}

        <div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}><I.Tag size={15}/><b style={{ fontSize: 14 }}>Límites y comisión de la pasarela</b></div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12 }}>
            {[['montoMin', 'Monto mínimo (Q)'], ['montoMax', 'Monto máximo (Q)'], ['comisionPct', 'Comisión %'], ['comisionFija', 'Comisión fija (Q)']].map(([k, l]) => (
              <div key={k}><label style={lbl}>{l}</label><input type="number" style={{ ...inp, fontFamily: t.mono }} value={f.limites[k]} onChange={(ev) => setF({ ...f, limites: { ...f.limites, [k]: ev.target.value } })}/></div>
            ))}
          </div>
        </div>

        {p.proveedor !== 'manual' && (
          <div style={{ padding: 14, borderRadius: 12, background: '#F6F7F9', border: `1px solid ${t.border}` }}>
            <div style={{ fontSize: 12.5, fontWeight: 700, color: t.text, marginBottom: 6 }}>URL de webhook — regístrala en el panel del proveedor</div>
            <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
              <code style={{ flex: 1, fontFamily: t.mono, fontSize: 12.5, color: t.brand, wordBreak: 'break-all' }}>{webhookUrl}</code>
              <button onClick={() => navigator.clipboard && navigator.clipboard.writeText(webhookUrl)} style={mBtn(t)}>Copiar</button>
            </div>
            {p.webhook && p.webhook.ultimoEvento && <div style={{ fontSize: 12, color: t.ter, marginTop: 6 }}>Último evento: {new Date(p.webhook.ultimoEvento).toLocaleString('es-GT')} · {p.webhook.eventosOk} OK · {p.webhook.eventosError} rechazados</div>}
          </div>
        )}

        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, padding: 14, borderRadius: 12, border: `1px solid ${f.activa ? '#1F8A5B55' : t.border}`, background: f.activa ? '#EAF7F0' : '#fff' }}>
          <div><b style={{ fontSize: 14, color: t.text }}>Pasarela activa</b><div style={{ fontSize: 12.5, color: t.sec }}>Al activarla, la app la usa de inmediato para los usos marcados. Exige credenciales y parámetros obligatorios completos.</div></div>
          <button onClick={() => setF({ ...f, activa: !f.activa })} style={{ width: 50, height: 30, borderRadius: 999, border: 'none', cursor: 'pointer', background: f.activa ? '#1F8A5B' : '#D4DCE6', position: 'relative', flexShrink: 0 }}>
            <span style={{ position: 'absolute', top: 2, left: f.activa ? 22 : 2, width: 26, height: 26, borderRadius: 999, background: '#fff', transition: 'left .2s', boxShadow: '0 2px 6px rgba(0,0,0,.2)' }}/>
          </button>
        </div>
      </div>
    </window.Modal>
  );
}
const mBtn = (t) => ({ height: 38, padding: '0 14px', borderRadius: 10, border: `1px solid ${t.border}`, background: '#fff', color: t.text, fontWeight: 700, cursor: 'pointer', fontFamily: t.font, fontSize: 13.5 });

function AyudaModal({ t, I, prov, onClose, onConfig }) {
  const H = window.PASARELAS_AYUDA || {};
  const h = H[prov] || H.general;
  if (!h) return null;
  const sec = (titulo, arr, numerado) => arr && arr.length ? (
    <div>
      <div style={{ fontSize: 12, fontWeight: 800, color: t.ter, textTransform: 'uppercase', letterSpacing: .8, marginBottom: 8 }}>{titulo}</div>
      {numerado ? <ol style={{ margin: 0, paddingLeft: 22, display: 'flex', flexDirection: 'column', gap: 8 }}>{arr.map((s, i) => <li key={i} style={{ fontSize: 14, color: t.text, lineHeight: 1.55 }}>{s}</li>)}</ol>
        : <ul style={{ margin: 0, paddingLeft: 20, display: 'flex', flexDirection: 'column', gap: 6 }}>{arr.map((s, i) => <li key={i} style={{ fontSize: 14, color: t.text, lineHeight: 1.5 }}>{s}</li>)}</ul>}
    </div>
  ) : null;
  return (
    <window.Modal title={h.titulo} sub={h.tiempo ? 'Tiempo típico de activación: ' + h.tiempo : 'Guía del administrador'} width={720} onClose={onClose}
      footer={<div style={{ display: 'flex', gap: 8, width: '100%' }}><span style={{ flex: 1 }}/>{onConfig && <button onClick={onConfig} style={{ ...mBtn(t), ...window.GOLD }}>Configurar ahora</button>}<button onClick={onClose} style={mBtn(t)}>Cerrar</button></div>}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
        {h.porque && <div style={{ padding: 14, borderRadius: 12, background: t.brand + '0F', border: `1px solid ${t.brand}33`, fontSize: 14, color: t.text, lineHeight: 1.55 }}>{h.porque}</div>}
        {sec('Requisitos', h.requisitos)}
        {sec('Pasos', h.pasos, true)}
        {sec('Seguridad', h.seguridad)}
        {H[prov] && H[prov].doc === undefined && prov !== 'general' && (
          <div style={{ fontSize: 12.5, color: t.ter }}>Cuando el proveedor entregue su documentación oficial, los nombres de campo se ajustan en <code style={{ fontFamily: t.mono }}>proveedores.js</code> y la llamada en el adaptador — esta pantalla no cambia.</div>
        )}
      </div>
    </window.Modal>
  );
}

window.PasarelasView = PasarelasView;
