// AGENTFORGE-IA — Log de actividad de usuarios

const AuditPanel = () => {
  const getToken = () => sessionStorage.getItem('af_token') || '';

  const [logs, setLogs] = React.useState([]);
  const [total, setTotal] = React.useState(0);
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState('');

  // Filtros
  const [search, setSearch] = React.useState('');
  const [category, setCategory] = React.useState('');
  const [actorEmail, setActorEmail] = React.useState('');
  const [dateFrom, setDateFrom] = React.useState('');
  const [dateTo, setDateTo] = React.useState('');
  const [successFilter, setSuccessFilter] = React.useState('');
  const [activeTab, setActiveTab] = React.useState('all'); // 'all' | 'access'

  // Paginación
  const [page, setPage] = React.useState(0);
  const PAGE_SIZE = 50;

  // Edición de notas
  const [editingNoteId, setEditingNoteId] = React.useState(null);
  const [noteValue, setNoteValue] = React.useState('');
  const [savingNote, setSavingNote] = React.useState(false);

  const CATEGORIES = [
    { value: 'auth',          label: 'Acceso',              color: '#60a5fa' },
    { value: 'user_mgmt',     label: 'Gestión de usuarios', color: '#a78bfa' },
    { value: 'mfa',           label: 'MFA / 2FA',           color: '#f59e0b' },
    { value: 'roles',         label: 'Roles y permisos',    color: '#34d399' },
    { value: 'subscription',  label: 'Suscripciones',       color: '#fb923c' },
    { value: 'integration',   label: 'Integraciones',       color: '#f472b6' },
    { value: 'billing',       label: 'Facturación',         color: '#fbbf24' },
    { value: 'configuracion', label: 'Configuración',       color: '#94a3b8' },
    { value: 'acciones',     label: 'Acciones',            color: '#ff5b1f' },
  ];
  const catMap = Object.fromEntries(CATEGORIES.map(c => [c.value, c]));

  const fetchLogs = React.useCallback(async (currentPage = 0) => {
    setLoading(true);
    setError('');
    try {
      const params = new URLSearchParams();
      const effectiveCategory = activeTab === 'access' ? 'auth' : category;
      if (search.trim())        params.set('search', search.trim());
      if (effectiveCategory)    params.set('category', effectiveCategory);
      if (actorEmail.trim())    params.set('actor_email', actorEmail.trim());
      if (dateFrom)             params.set('date_from', dateFrom + 'T00:00:00');
      if (dateTo)               params.set('date_to', dateTo + 'T23:59:59');
      if (successFilter === 'ok')    params.set('success', 'true');
      if (successFilter === 'error') params.set('success', 'false');
      params.set('limit', String(PAGE_SIZE));
      params.set('offset', String(currentPage * PAGE_SIZE));

      const res = await fetch('/api/v1/audit/logs?' + params.toString(), {
        headers: { Authorization: 'Bearer ' + getToken() },
      });
      if (!res.ok) { setError('Error cargando actividad'); return; }
      const data = await res.json();
      setLogs(data.items || []);
      setTotal(data.total || 0);
      setPage(currentPage);
    } catch (_) {
      setError('Error de red');
    } finally {
      setLoading(false);
    }
  }, [search, category, actorEmail, dateFrom, dateTo, successFilter, activeTab]);

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

  const handleExport = async () => {
    const params = new URLSearchParams();
    const effectiveCategory = activeTab === 'access' ? 'auth' : category;
    if (search.trim())        params.set('search', search.trim());
    if (effectiveCategory)    params.set('category', effectiveCategory);
    if (actorEmail.trim())    params.set('actor_email', actorEmail.trim());
    if (dateFrom)             params.set('date_from', dateFrom + 'T00:00:00');
    if (dateTo)               params.set('date_to', dateTo + 'T23:59:59');
    if (successFilter === 'ok')    params.set('success', 'true');
    if (successFilter === 'error') params.set('success', 'false');
    const res = await fetch('/api/v1/audit/logs/export?' + params.toString(), {
      headers: { Authorization: 'Bearer ' + getToken() },
    });
    if (!res.ok) { window.afNotify && window.afNotify('Error al exportar', 'error'); return; }
    const blob = await res.blob();
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    const cd = res.headers.get('Content-Disposition') || '';
    const m = cd.match(/filename="(.+?)"/);
    a.download = m ? m[1] : 'actividad_usuarios.csv';
    a.click();
    URL.revokeObjectURL(url);
  };

  const startEditNote = (log) => { setEditingNoteId(log.id); setNoteValue(log.notes || ''); };

  const saveNote = async (logId) => {
    setSavingNote(true);
    try {
      const res = await fetch(`/api/v1/audit/logs/${logId}/notes`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + getToken() },
        body: JSON.stringify({ notes: noteValue.trim() || null }),
      });
      if (!res.ok) { window.afNotify && window.afNotify('Error guardando nota', 'error'); return; }
      const updated = await res.json();
      setLogs(prev => prev.map(l => l.id === logId ? { ...l, ...updated } : l));
      setEditingNoteId(null);
      window.afNotify && window.afNotify('Nota guardada');
    } catch (_) { window.afNotify && window.afNotify('Error de red', 'error'); }
    finally { setSavingNote(false); }
  };

  const formatDT = (iso) => {
    if (!iso) return '—';
    const d = new Date(iso);
    return d.toLocaleDateString('es-ES') + ' ' + d.toLocaleTimeString('es-ES', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
  };

  const totalPages = Math.ceil(total / PAGE_SIZE);

  // ── Estilos ──────────────────────────────────────────────────────────────────
  const wrap     = { padding: '24px 28px', color: 'var(--text)', fontFamily: '"Inter Tight","Inter",sans-serif', minHeight: '100vh' };
  const hdr      = { display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', marginBottom: 20 };
  const inp      = { background: 'var(--bg-2)', border: '1px solid var(--border)', borderRadius: 6, padding: '6px 10px', fontSize: 12.5, color: 'var(--text)', fontFamily: 'inherit', outline: 'none' };
  const sel      = { ...inp, cursor: 'pointer' };
  const btn      = { padding: '6px 14px', borderRadius: 6, border: '1px solid var(--border)', cursor: 'pointer', fontSize: 12.5, fontWeight: 600, fontFamily: 'inherit', background: 'var(--bg-2)', color: 'var(--text-2)' };
  const btnP     = { ...btn, background: 'var(--brand)', color: '#fff', border: 'none' };
  const tabBtn   = (a) => ({ padding: '6px 14px', border: 'none', borderRadius: 6, cursor: 'pointer', fontSize: 12.5, fontWeight: 600, fontFamily: 'inherit', background: a ? 'var(--brand)' : 'transparent', color: a ? '#fff' : 'var(--text-2)', transition: 'all 0.15s' });
  const thS      = { padding: '9px 12px', textAlign: 'left', color: 'var(--text-2)', fontWeight: 600, fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.06em', borderBottom: '1px solid var(--border)', whiteSpace: 'nowrap' };
  const tdS      = (fail) => ({ padding: '10px 12px', borderBottom: '1px solid var(--border)', verticalAlign: 'top', background: fail ? 'rgba(248,113,113,0.04)' : 'transparent' });
  const badge    = (color, bg) => ({ display: 'inline-flex', alignItems: 'center', padding: '2px 7px', borderRadius: 4, fontSize: 11, fontWeight: 600, color, background: bg });
  const mono     = { fontFamily: '"JetBrains Mono",ui-monospace,monospace', fontSize: 11.5 };
  const noteInp  = { ...inp, border: '1px solid var(--brand)', width: 180, resize: 'none', fontSize: 12 };

  const catBadge = (cat) => {
    const c = catMap[cat] || { label: cat, color: '#888' };
    return <span style={{ ...badge(c.color, c.color + '1a'), textTransform: 'uppercase', letterSpacing: '0.05em' }}>{c.label}</span>;
  };

  const okBadge = (ok) => ok
    ? <span style={badge('#34d399', 'rgba(52,211,153,0.12)')}>✓ OK</span>
    : <span style={badge('#f87171', 'rgba(248,113,113,0.12)')}>✗ Error</span>;

  const accessTypeBadge = (action) => {
    if (action === 'auth.login')        return <span style={badge('#34d399', 'rgba(52,211,153,0.12)')}>→ Inicio de sesión</span>;
    if (action === 'auth.logout')       return <span style={badge('#60a5fa', 'rgba(96,165,250,0.12)')}>← Cierre de sesión</span>;
    if (action === 'auth.login_failed') return <span style={badge('#f87171', 'rgba(248,113,113,0.12)')}>⊘ Acceso fallido</span>;
    return null;
  };

  const colCount = activeTab === 'access' ? 6 : 7;

  return (
    <div style={wrap}>

      {/* Header */}
      <div style={hdr}>
        <div>
          <div style={{ fontSize: 20, fontWeight: 700, letterSpacing: '-0.02em' }}>Actividad de usuarios</div>
          <div style={{ fontSize: 13, color: 'var(--text-2)', marginTop: 3 }}>
            Registro exhaustivo de accesos y acciones de todos los usuarios · Retención: 60 días · <strong>{total.toLocaleString('es-ES')}</strong> entradas
          </div>
        </div>
        <button style={btnP} onClick={handleExport}>↓ Exportar CSV</button>
      </div>

      {/* Tabs */}
      <div style={{ display: 'flex', gap: 4, marginBottom: 16, background: 'var(--bg-2)', borderRadius: 8, padding: 3, border: '1px solid var(--border)', width: 'fit-content' }}>
        <button style={tabBtn(activeTab === 'all')} onClick={() => { setActiveTab('all'); setPage(0); }}>Todas las acciones</button>
        <button style={tabBtn(activeTab === 'access')} onClick={() => { setActiveTab('access'); setPage(0); }}>Accesos (inicio / cierre de sesión)</button>
      </div>

      {/* Filtros */}
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 16, alignItems: 'center' }}>
        <input style={{ ...inp, width: 220 }} placeholder="Buscar usuario, acción, recurso…" value={search} onChange={e => setSearch(e.target.value)} onKeyDown={e => e.key === 'Enter' && fetchLogs(0)} />
        {activeTab === 'all' && (
          <select style={sel} value={category} onChange={e => setCategory(e.target.value)}>
            <option value="">Tipo de acción: todos</option>
            {CATEGORIES.map(c => <option key={c.value} value={c.value}>{c.label}</option>)}
          </select>
        )}
        <input style={{ ...inp, width: 190 }} placeholder="Email del usuario" value={actorEmail} onChange={e => setActorEmail(e.target.value)} />
        <input style={{ ...inp, width: 130 }} type="date" value={dateFrom} onChange={e => setDateFrom(e.target.value)} title="Desde" />
        <span style={{ color: 'var(--text-2)', fontSize: 12 }}>—</span>
        <input style={{ ...inp, width: 130 }} type="date" value={dateTo} onChange={e => setDateTo(e.target.value)} title="Hasta" />
        <select style={sel} value={successFilter} onChange={e => setSuccessFilter(e.target.value)}>
          <option value="">Estado: todos</option>
          <option value="ok">Éxito</option>
          <option value="error">Error</option>
        </select>
        <button style={btn} onClick={() => { setSearch(''); setCategory(''); setActorEmail(''); setDateFrom(''); setDateTo(''); setSuccessFilter(''); setPage(0); }}>Limpiar</button>
        <button style={btnP} onClick={() => fetchLogs(0)}>Buscar</button>
      </div>

      {error && <div style={{ background: 'rgba(248,113,113,0.1)', border: '1px solid rgba(248,113,113,0.3)', borderRadius: 6, padding: '10px 14px', color: '#f87171', fontSize: 12.5, marginBottom: 14 }}>{error}</div>}

      {/* Tabla */}
      <div style={{ background: 'var(--bg-2)', borderRadius: 10, border: '1px solid var(--border)', overflow: 'auto' }}>
        <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12.5 }}>
          <thead>
            <tr>
              <th style={thS}>Fecha y hora</th>
              <th style={thS}>Usuario</th>
              {activeTab === 'all' && <th style={thS}>Tipo</th>}
              <th style={thS}>Qué hizo</th>
              <th style={thS}>Sobre qué</th>
              {activeTab === 'access' && <th style={thS}>Resultado</th>}
              {activeTab === 'all' && <th style={thS}>Estado</th>}
              <th style={{ ...thS, minWidth: 170 }}>Notas <span style={{ fontWeight: 400, fontSize: 10, textTransform: 'none' }}>(editables)</span></th>
            </tr>
          </thead>
          <tbody>
            {loading && (
              <tr><td colSpan={colCount} style={{ ...tdS(), textAlign: 'center', padding: 36, color: 'var(--text-2)' }}>Cargando actividad…</td></tr>
            )}
            {!loading && logs.length === 0 && (
              <tr><td colSpan={colCount} style={{ ...tdS(), textAlign: 'center', padding: 36, color: 'var(--text-2)' }}>
                Sin registros para los filtros seleccionados
              </td></tr>
            )}
            {!loading && logs.map(log => (
              <tr key={log.id}
                onMouseEnter={e => { e.currentTarget.style.background = 'rgba(255,255,255,0.025)'; }}
                onMouseLeave={e => { e.currentTarget.style.background = 'transparent'; }}
              >
                {/* Fecha/hora */}
                <td style={{ ...tdS(!log.success), ...mono, whiteSpace: 'nowrap', fontSize: 12 }}>
                  {formatDT(log.created_at)}
                </td>

                {/* Usuario */}
                <td style={tdS(!log.success)}>
                  <div style={{ fontWeight: 600, fontSize: 13 }}>{log.actor_full_name || log.actor_email}</div>
                  <div style={{ fontSize: 11, color: 'var(--text-2)', marginTop: 1, ...mono }}>{log.actor_email}</div>
                  {log.actor_is_admin && <span style={{ ...badge('#f472b6', 'rgba(244,114,182,0.12)'), fontSize: 10, marginTop: 3, display: 'inline-flex' }}>Admin</span>}
                </td>

                {/* Tipo de acción (solo en "todas") */}
                {activeTab === 'all' && (
                  <td style={tdS(!log.success)}>{catBadge(log.category)}</td>
                )}

                {/* Qué hizo */}
                <td style={tdS(!log.success)}>
                  {activeTab === 'access'
                    ? accessTypeBadge(log.action)
                    : (
                      <>
                        <div style={{ fontWeight: 500, color: 'var(--text)' }}>{log.action_label}</div>
                        <div style={{ fontSize: 11, color: 'var(--text-2)', marginTop: 2, ...mono }}>{log.action}</div>
                        {log.detail && Object.keys(log.detail).length > 0 && (
                          <details style={{ marginTop: 4 }}>
                            <summary style={{ fontSize: 11, color: 'var(--text-2)', cursor: 'pointer' }}>Ver detalle</summary>
                            <pre style={{ fontSize: 10.5, color: 'var(--text-2)', margin: '4px 0 0', whiteSpace: 'pre-wrap', maxWidth: 280 }}>
                              {JSON.stringify(log.detail, null, 2)}
                            </pre>
                          </details>
                        )}
                      </>
                    )
                  }
                </td>

                {/* Sobre qué recurso */}
                <td style={tdS(!log.success)}>
                  {log.resource_type && <span style={{ ...badge('#888', 'rgba(128,128,128,0.12)'), display: 'inline-block', marginBottom: 3 }}>{log.resource_type}</span>}
                  {log.resource_label && <div style={{ fontSize: 12 }}>{log.resource_label}</div>}
                </td>

                {/* Estado */}
                <td style={tdS(!log.success)}>{okBadge(log.success)}</td>

                {/* Notas editables */}
                <td style={tdS(!log.success)}>
                  {editingNoteId === log.id ? (
                    <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                      <textarea style={noteInp} rows={2} value={noteValue} onChange={e => setNoteValue(e.target.value)} placeholder="Escribe una nota…" autoFocus />
                      <div style={{ display: 'flex', gap: 4 }}>
                        <button style={{ ...btnP, padding: '3px 10px', fontSize: 11 }} disabled={savingNote} onClick={() => saveNote(log.id)}>
                          {savingNote ? 'Guardando…' : 'Guardar'}
                        </button>
                        <button style={{ ...btn, padding: '3px 10px', fontSize: 11 }} onClick={() => setEditingNoteId(null)}>Cancelar</button>
                      </div>
                      {log.notes_edited_by && <div style={{ fontSize: 10, color: 'var(--text-2)' }}>Editado por {log.notes_edited_by}</div>}
                    </div>
                  ) : (
                    <div style={{ display: 'flex', alignItems: 'flex-start', gap: 5 }}>
                      <span style={{ flex: 1, fontSize: 12, color: log.notes ? 'var(--text)' : 'var(--text-2)', fontStyle: log.notes ? 'normal' : 'italic' }}>
                        {log.notes || 'Sin nota'}
                      </span>
                      <button
                        style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-2)', fontSize: 13, padding: '0 2px', flexShrink: 0, lineHeight: 1 }}
                        onClick={() => startEditNote(log)}
                        title="Añadir / editar nota"
                      >✎</button>
                    </div>
                  )}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {/* Paginación */}
      {totalPages > 1 && (
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 16, justifyContent: 'flex-end' }}>
          <span style={{ fontSize: 12, color: 'var(--text-2)' }}>Página {page + 1} de {totalPages} · {total.toLocaleString('es-ES')} registros</span>
          <button style={{ ...btn, opacity: page === 0 ? 0.4 : 1 }} disabled={page === 0} onClick={() => fetchLogs(page - 1)}>← Anterior</button>
          <button style={{ ...btn, opacity: page >= totalPages - 1 ? 0.4 : 1 }} disabled={page >= totalPages - 1} onClick={() => fetchLogs(page + 1)}>Siguiente →</button>
        </div>
      )}

    </div>
  );
};

window.AuditPanel = AuditPanel;
