'use client';

import { useEffect, useState } from 'react';
import { apiFetch } from '@/lib/api';
import { Input } from '@/components/input';
import { Button } from '@/components/ui/button';

interface Row {
  entry: {
    id: string;
    orgId: string | null;
    userId: string | null;
    action: string;
    resourceType: string | null;
    resourceId: string | null;
    metadata: Record<string, unknown> | null;
    ipAddress: string | null;
    createdAt: string;
  };
  userEmail: string | null;
}

const ACTION_FILTERS = [
  '',
  'auth.login',
  'auth.logout',
  'admin.login',
  'server.create',
  'server.iterate',
  'server.delete',
  'admin.user.update',
  'admin.user.delete',
  'admin.org.update',
  'admin.server.rebuild',
  'admin.server.delete',
  'admin.prompt.update',
];

export default function AdminAuditPage() {
  const [rows, setRows] = useState<Row[] | null>(null);
  const [action, setAction] = useState('');
  const [search, setSearch] = useState('');

  useEffect(() => {
    apiFetch<{ entries: Row[] }>(`/v1/admin/audit${action ? `?action=${action}` : ''}`)
      .then((r) => setRows(r.entries))
      .catch(() => setRows([]));
  }, [action]);

  function exportCsv() {
    if (!rows) return;
    const header = ['when', 'action', 'user', 'resource', 'ip', 'metadata'];
    const lines = rows.map((r) =>
      [
        new Date(r.entry.createdAt).toISOString(),
        r.entry.action,
        r.userEmail ?? '',
        `${r.entry.resourceType ?? ''}/${r.entry.resourceId ?? ''}`,
        r.entry.ipAddress ?? '',
        r.entry.metadata ? JSON.stringify(r.entry.metadata).replace(/"/g, '""') : '',
      ]
        .map((v) => `"${String(v).replace(/"/g, '""')}"`)
        .join(','),
    );
    const csv = [header.join(','), ...lines].join('\n');
    const blob = new Blob([csv], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `bmm-audit-${Date.now()}.csv`;
    a.click();
    URL.revokeObjectURL(url);
  }

  const visible = rows?.filter((r) =>
    search
      ? r.entry.action.includes(search) ||
        r.userEmail?.includes(search) ||
        r.entry.resourceId?.includes(search) ||
        r.entry.ipAddress?.includes(search)
      : true,
  );

  return (
    <div className="px-8 py-8">
      <header className="mb-6 flex items-baseline justify-between">
        <div>
          <h1 className="text-[22px] font-semibold tracking-tight">Audit log</h1>
          <p className="mt-1 text-[13px] text-[--color-fg-muted]">
            System-wide. {visible?.length ?? 0} visible.
          </p>
        </div>
        <Button variant="secondary" size="md" onClick={exportCsv}>
          Export CSV
        </Button>
      </header>

      <div className="mb-4 flex flex-wrap gap-2">
        <select
          value={action}
          onChange={(e) => setAction(e.target.value)}
          className="h-8 rounded-md border border-[--color-border] bg-[--color-bg-subtle] px-2 text-[13px] focus:border-[--color-accent] focus:outline-none"
        >
          {ACTION_FILTERS.map((a) => (
            <option key={a} value={a}>
              {a ? a : 'All actions'}
            </option>
          ))}
        </select>
        <Input
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          placeholder="Filter by user email, resource id, or ip…"
          className="w-96"
        />
      </div>

      <div className="panel">
        {!visible && (
          <p className="px-4 py-3 text-[12.5px] text-[--color-fg-muted]">Loading…</p>
        )}
        {visible && visible.length === 0 && (
          <p className="px-4 py-12 text-center text-[13px] text-[--color-fg-muted]">No matches.</p>
        )}
        {visible && visible.length > 0 && (
          <table className="w-full text-[12px]">
            <thead className="border-b border-[--color-border] text-[--color-fg-subtle]">
              <tr>
                <th className="px-4 py-2 text-left font-medium">When</th>
                <th className="px-4 py-2 text-left font-medium">Action</th>
                <th className="px-4 py-2 text-left font-medium">User</th>
                <th className="px-4 py-2 text-left font-medium">Resource</th>
                <th className="px-4 py-2 text-left font-medium">IP</th>
                <th className="px-4 py-2 text-left font-medium">Metadata</th>
              </tr>
            </thead>
            <tbody>
              {visible.map((r) => (
                <tr key={r.entry.id} className="border-b border-[--color-border] last:border-0">
                  <td className="px-4 py-2 mono text-[--color-fg-muted] whitespace-nowrap">
                    {new Date(r.entry.createdAt).toLocaleString()}
                  </td>
                  <td className="px-4 py-2">
                    <span className="mono rounded-full border border-[--color-border] bg-[--color-bg-subtle] px-2 py-0.5 text-[11px]">
                      {r.entry.action}
                    </span>
                  </td>
                  <td className="px-4 py-2 mono text-[--color-fg-muted]">{r.userEmail ?? '—'}</td>
                  <td className="px-4 py-2 mono text-[--color-fg-muted]">
                    {r.entry.resourceType
                      ? `${r.entry.resourceType}/${r.entry.resourceId?.slice(0, 8) ?? '—'}`
                      : '—'}
                  </td>
                  <td className="px-4 py-2 mono text-[--color-fg-muted]">{r.entry.ipAddress ?? '—'}</td>
                  <td className="px-4 py-2 mono text-[10.5px] text-[--color-fg-subtle] max-w-[280px] truncate">
                    {r.entry.metadata ? JSON.stringify(r.entry.metadata) : '—'}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
}
