'use client';

/**
 * app/admin/audit-table.jsx — Client component.
 *
 * Fetches audit_logs rows via lib/audit-search.js (through an API shim)
 * and renders a paginated, filterable table.
 *
 * Props:
 *   orgId {string} — restrict to this org's audit rows.
 *
 * Columns: user_id, action (type), summary, status, IP (/24 truncated), timestamp.
 * Filters: user_id, action type prefix, since/until dates, IP, target_type.
 */

import { useState, useEffect, useCallback, useTransition } from 'react';

const PAGE_SIZE = 50;

// Truncate IP to /24 for display (e.g. 10.0.1.55 → 10.0.1.x).
function truncateIp(ip) {
  if (!ip) return '—';
  const parts = ip.split('.');
  if (parts.length === 4) return `${parts[0]}.${parts[1]}.${parts[2]}.x`;
  return ip.slice(0, 20);
}

function formatTime(ts) {
  if (!ts) return '—';
  try {
    return new Date(ts).toLocaleString(undefined, {
      year: 'numeric', month: '2-digit', day: '2-digit',
      hour: '2-digit', minute: '2-digit',
    });
  } catch {
    return String(ts).slice(0, 19).replace('T', ' ');
  }
}

function statusClass(status) {
  if (status === 'success') return 'admin-pill ok';
  if (status === 'denied') return 'admin-pill warn';
  if (status === 'error') return 'admin-pill danger';
  return 'admin-pill neutral';
}

export default function AuditTable({ orgId }) {
  const [rows, setRows] = useState([]);
  const [total, setTotal] = useState(null);
  const [cursor, setCursor] = useState(0);
  const [nextCursor, setNextCursor] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [isPending, startTransition] = useTransition();

  // Filter state
  const [filters, setFilters] = useState({
    user_id: '',
    action: '',
    since: '',
    until: '',
    ip: '',
    target_type: '',
  });

  const fetchRows = useCallback(async (currentFilters, currentCursor) => {
    setLoading(true);
    setError(null);
    try {
      const params = new URLSearchParams();
      params.set('org_id', orgId);
      params.set('limit', String(PAGE_SIZE));
      params.set('cursor', String(currentCursor));
      if (currentFilters.user_id.trim()) params.set('user_id', currentFilters.user_id.trim());
      if (currentFilters.action.trim()) params.set('query', currentFilters.action.trim());
      if (currentFilters.since.trim()) params.set('since', currentFilters.since.trim());
      if (currentFilters.until.trim()) params.set('until', currentFilters.until.trim());
      if (currentFilters.ip.trim()) params.set('ip', currentFilters.ip.trim());
      if (currentFilters.target_type.trim()) params.set('action_target_type', currentFilters.target_type.trim());

      const res = await fetch(`/api/audit/search?${params.toString()}`);
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data = await res.json();

      // audit-search returns { rows, next_cursor }.
      // We filter client-side to source === 'audit_logs' only.
      const auditRows = (data.rows || []).filter(r => r.source === 'audit_logs');
      setRows(auditRows);
      setNextCursor(data.next_cursor || null);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  }, [orgId]);

  useEffect(() => {
    fetchRows(filters, cursor);
  }, [fetchRows, filters, cursor]);

  function handleFilterChange(key, value) {
    startTransition(() => {
      setCursor(0);
      setFilters(prev => ({ ...prev, [key]: value }));
    });
  }

  function handleReset() {
    startTransition(() => {
      setCursor(0);
      setFilters({ user_id: '', action: '', since: '', until: '', ip: '', target_type: '' });
    });
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>

      {/* Filters */}
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem', alignItems: 'flex-end' }}>
        <label style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', fontSize: '0.8em' }}>
          <span style={{ color: 'var(--color-muted, #888)' }}>User ID</span>
          <input
            className="admin-input"
            style={{ width: '160px' }}
            value={filters.user_id}
            onChange={e => handleFilterChange('user_id', e.target.value)}
            placeholder="user-..."
          />
        </label>
        <label style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', fontSize: '0.8em' }}>
          <span style={{ color: 'var(--color-muted, #888)' }}>Action / keyword</span>
          <input
            className="admin-input"
            style={{ width: '180px' }}
            value={filters.action}
            onChange={e => handleFilterChange('action', e.target.value)}
            placeholder="artifact.read..."
          />
        </label>
        <label style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', fontSize: '0.8em' }}>
          <span style={{ color: 'var(--color-muted, #888)' }}>Target type</span>
          <select
            className="admin-select"
            value={filters.target_type}
            onChange={e => handleFilterChange('target_type', e.target.value)}
          >
            <option value="">All</option>
            <option value="artifact">artifact</option>
            <option value="user">user</option>
            <option value="org">org</option>
            <option value="tool">tool</option>
            <option value="share_link">share_link</option>
          </select>
        </label>
        <label style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', fontSize: '0.8em' }}>
          <span style={{ color: 'var(--color-muted, #888)' }}>Since</span>
          <input
            type="date"
            className="admin-input"
            value={filters.since}
            onChange={e => handleFilterChange('since', e.target.value)}
          />
        </label>
        <label style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', fontSize: '0.8em' }}>
          <span style={{ color: 'var(--color-muted, #888)' }}>Until</span>
          <input
            type="date"
            className="admin-input"
            value={filters.until}
            onChange={e => handleFilterChange('until', e.target.value)}
          />
        </label>
        <label style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', fontSize: '0.8em' }}>
          <span style={{ color: 'var(--color-muted, #888)' }}>IP</span>
          <input
            className="admin-input"
            style={{ width: '120px' }}
            value={filters.ip}
            onChange={e => handleFilterChange('ip', e.target.value)}
            placeholder="10.0.1.55"
          />
        </label>
        <button className="admin-btn-sm" onClick={handleReset} style={{ alignSelf: 'flex-end' }}>
          Reset filters
        </button>
      </div>

      {/* Status line */}
      {error && (
        <div style={{ color: '#c0392b', fontSize: '0.85em', padding: '0.5rem 0' }}>
          Error loading audit log: {error}
        </div>
      )}

      {/* Table */}
      <div style={{ overflowX: 'auto' }}>
        <table className="admin-table" style={{ fontSize: '0.82em', width: '100%' }}>
          <thead>
            <tr>
              <th>Time</th>
              <th>Action</th>
              <th>Summary</th>
              <th>Status</th>
              <th>User</th>
              <th>IP (/24)</th>
            </tr>
          </thead>
          <tbody>
            {loading && (
              <tr>
                <td colSpan={6} style={{ textAlign: 'center', padding: '2rem', color: 'var(--color-muted, #888)' }}>
                  Loading...
                </td>
              </tr>
            )}
            {!loading && rows.length === 0 && (
              <tr>
                <td colSpan={6} style={{ textAlign: 'center', padding: '2rem', color: 'var(--color-muted, #888)' }}>
                  No audit rows found for the current filters.
                </td>
              </tr>
            )}
            {!loading && rows.map(row => (
              <tr key={row.id}>
                <td style={{ whiteSpace: 'nowrap', color: 'var(--color-muted, #888)' }}>
                  {formatTime(row.time)}
                </td>
                <td style={{ fontFamily: 'var(--font-mono-brand, monospace)', wordBreak: 'break-all', maxWidth: '180px' }}>
                  {row.action}
                </td>
                <td style={{ maxWidth: '260px' }}>
                  <span title={row.summary} style={{ display: 'block', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                    {row.summary || '—'}
                  </span>
                </td>
                <td>
                  {row.status ? (
                    <span className={statusClass(row.status)}>{row.status}</span>
                  ) : '—'}
                </td>
                <td style={{ fontFamily: 'var(--font-mono-brand, monospace)', fontSize: '0.9em', maxWidth: '140px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                  {row.user_id || <span style={{ color: 'var(--color-muted, #888)' }}>system</span>}
                </td>
                <td style={{ fontFamily: 'var(--font-mono-brand, monospace)', fontSize: '0.9em', color: 'var(--color-muted, #888)' }}>
                  {truncateIp(row.ip)}
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {/* Pagination */}
      <div style={{ display: 'flex', gap: '0.75rem', alignItems: 'center', fontSize: '0.85em' }}>
        <button
          className="admin-btn-sm"
          disabled={cursor === 0 || loading}
          onClick={() => setCursor(Math.max(0, cursor - PAGE_SIZE))}
        >
          Previous
        </button>
        <span style={{ color: 'var(--color-muted, #888)' }}>
          Showing {cursor + 1}–{cursor + rows.length}
        </span>
        <button
          className="admin-btn-sm"
          disabled={!nextCursor || loading}
          onClick={() => nextCursor && setCursor(parseInt(nextCursor, 10))}
        >
          Next
        </button>
      </div>
    </div>
  );
}
