import { useState, useCallback } from 'react';
import { useQuery } from '@tanstack/react-query';
import { api } from '../../lib/api';
import type { AuditLogEntry, AuditLogQuery, AuditSeverity, User } from '../../types/api';

const PAGE_SIZE = 50;

const SEVERITY_COLORS: Record<AuditSeverity, string> = {
  info: 'bg-blue-100 text-blue-800',
  warning: 'bg-yellow-100 text-yellow-800',
  error: 'bg-red-100 text-red-800',
  critical: 'bg-red-200 text-red-900 font-semibold',
};

const ACTION_GROUPS: Record<string, string[]> = {
  Auth: ['login_success', 'login_failure', 'logout', 'token_refresh', 'password_change', 'password_reset'],
  Jobs: ['job_create', 'job_update', 'job_delete', 'job_approve', 'job_reject', 'job_cancel', 'job_status_change'],
  VTT: ['vtt_edit', 'vtt_approve', 'vtt_reject'],
  Files: ['file_upload', 'file_download', 'file_delete', 'file_access'],
  Users: ['user_create', 'user_update', 'user_delete', 'user_role_change', 'user_activate', 'user_deactivate'],
  Security: ['rate_limit_exceeded', 'validation_failure', 'unauthorized_access', 'suspicious_activity'],
  Admin: ['admin_config_change', 'admin_system_action', 'admin_data_export', 'admin_audit_access'],
};

type Tab = 'all' | 'security' | 'user';

function formatDate(ts: string) {
  return new Date(ts).toLocaleString('en-GB', {
    day: '2-digit', month: '2-digit', year: '2-digit',
    hour: '2-digit', minute: '2-digit', second: '2-digit',
  });
}

function EntryDetail({ entry }: { entry: AuditLogEntry }) {
  return (
    <div className="p-4 bg-gray-50 border-t text-sm space-y-2">
      <div className="grid grid-cols-2 gap-x-8 gap-y-1">
        {entry.ip_address && <div><span className="text-gray-500">IP:</span> {entry.ip_address}</div>}
        {entry.request_id && <div><span className="text-gray-500">Request ID:</span> <code className="text-xs">{entry.request_id}</code></div>}
        {entry.resource_type && <div><span className="text-gray-500">Resource:</span> {entry.resource_type} {entry.resource_id && <code className="text-xs">({entry.resource_id})</code>}</div>}
        {entry.user_agent && <div className="col-span-2"><span className="text-gray-500">User Agent:</span> <span className="text-xs">{entry.user_agent}</span></div>}
      </div>
      {entry.error_message && (
        <div className="text-red-600"><span className="text-gray-500">Error:</span> {entry.error_message}</div>
      )}
      {entry.details && Object.keys(entry.details).length > 0 && (
        <pre className="bg-white border rounded p-2 text-xs overflow-auto max-h-40">
          {JSON.stringify(entry.details, null, 2)}
        </pre>
      )}
    </div>
  );
}

function AuditTable({ logs, isLoading }: { logs: AuditLogEntry[]; isLoading: boolean }) {
  const [expanded, setExpanded] = useState<string | null>(null);

  if (isLoading) {
    return (
      <div className="animate-pulse space-y-2">
        {Array.from({ length: 8 }).map((_, i) => (
          <div key={i} className="h-10 bg-gray-200 rounded" />
        ))}
      </div>
    );
  }

  if (logs.length === 0) {
    return <p className="text-gray-500 text-center py-8">No audit log entries found.</p>;
  }

  return (
    <div className="overflow-x-auto rounded-lg border border-gray-200">
      <table className="min-w-full divide-y divide-gray-200 text-sm">
        <thead className="bg-gray-50">
          <tr>
            <th className="px-3 py-2 text-left font-medium text-gray-600">Time</th>
            <th className="px-3 py-2 text-left font-medium text-gray-600">Action</th>
            <th className="px-3 py-2 text-left font-medium text-gray-600">Sev</th>
            <th className="px-3 py-2 text-left font-medium text-gray-600">Actor</th>
            <th className="px-3 py-2 text-left font-medium text-gray-600">Description</th>
            <th className="px-3 py-2 text-left font-medium text-gray-600">Status</th>
          </tr>
        </thead>
        <tbody className="bg-white divide-y divide-gray-100">
          {logs.map((entry, idx) => {
            const key = entry.id ?? `${idx}`;
            const isOpen = expanded === key;
            return [
              <tr
                key={key}
                className="hover:bg-gray-50 cursor-pointer"
                onClick={() => setExpanded(isOpen ? null : key)}
              >
                <td className="px-3 py-2 whitespace-nowrap text-gray-500 font-mono text-xs">
                  {formatDate(entry.timestamp)}
                </td>
                <td className="px-3 py-2 font-mono text-xs text-gray-800">{entry.action}</td>
                <td className="px-3 py-2">
                  <span className={`px-1.5 py-0.5 rounded text-xs ${SEVERITY_COLORS[entry.severity]}`}>
                    {entry.severity}
                  </span>
                </td>
                <td className="px-3 py-2 text-xs">
                  {entry.user_email ? (
                    <span title={`${entry.user_role ?? ''}`}>{entry.user_email}</span>
                  ) : <span className="text-gray-400">—</span>}
                </td>
                <td className="px-3 py-2 text-gray-700 max-w-xs truncate">{entry.description}</td>
                <td className="px-3 py-2">
                  {entry.success
                    ? <span className="text-green-600 font-medium">OK</span>
                    : <span className="text-red-600 font-medium">FAIL</span>}
                </td>
              </tr>,
              isOpen && (
                <tr key={`${key}-detail`}>
                  <td colSpan={6} className="p-0">
                    <EntryDetail entry={entry} />
                  </td>
                </tr>
              ),
            ];
          })}
        </tbody>
      </table>
    </div>
  );
}

export function AuditLog() {
  const [tab, setTab] = useState<Tab>('all');
  const [page, setPage] = useState(0);
  const [filters] = useState<AuditLogQuery>({ limit: PAGE_SIZE });
  const [search, setSearch] = useState('');
  const [actionFilter, setActionFilter] = useState('');
  const [severityFilter, setSeverityFilter] = useState('');
  const [successFilter, setSuccessFilter] = useState('');
  const [securityHours, setSecurityHours] = useState(24);
  const [activeUserId, setActiveUserId] = useState('');

  const usersQuery = useQuery({
    queryKey: ['admin-users-all'],
    queryFn: () => api.listUsers({ size: 500, active_only: false }),
    enabled: tab === 'user',
    staleTime: 60_000,
  });

  const buildQuery = useCallback((): AuditLogQuery => ({
    ...filters,
    skip: page * PAGE_SIZE,
    limit: PAGE_SIZE,
    search: search || undefined,
    action: actionFilter || undefined,
    severity: (severityFilter as AuditSeverity) || undefined,
    success: successFilter === '' ? undefined : successFilter === 'true',
  }), [filters, page, search, actionFilter, severityFilter, successFilter]);

  const allQuery = useQuery({
    queryKey: ['audit-logs', buildQuery()],
    queryFn: () => api.getAuditLogs(buildQuery()),
    enabled: tab === 'all',
    refetchInterval: 30_000,
  });

  const securityQuery = useQuery({
    queryKey: ['audit-security', securityHours],
    queryFn: () => api.getSecurityEvents(securityHours),
    enabled: tab === 'security',
    refetchInterval: 30_000,
  });

  const userQuery = useQuery({
    queryKey: ['audit-user', activeUserId],
    queryFn: () => api.getUserAuditLogs(activeUserId),
    enabled: tab === 'user' && !!activeUserId,
  });

  const handleSearch = (e: React.FormEvent) => {
    e.preventDefault();
    setPage(0);
  };

  const totalPages = tab === 'all' && allQuery.data
    ? Math.ceil(allQuery.data.total_count / PAGE_SIZE)
    : 1;

  return (
    <div className="container mx-auto px-4 py-8">
      <div className="flex items-center justify-between mb-6">
        <h1 className="text-3xl font-bold text-gray-900">Audit Log</h1>
        <span className="text-sm text-gray-400">Auto-refreshes every 30s</span>
      </div>

      {/* Tabs */}
      <div className="flex gap-1 mb-6 border-b border-gray-200">
        {(['all', 'security', 'user'] as Tab[]).map(t => (
          <button
            key={t}
            onClick={() => setTab(t)}
            className={`px-4 py-2 text-sm font-medium capitalize border-b-2 transition-colors ${
              tab === t
                ? 'border-blue-600 text-blue-600'
                : 'border-transparent text-gray-500 hover:text-gray-700'
            }`}
          >
            {t === 'all' ? 'All Events' : t === 'security' ? 'Security Events' : 'User Activity'}
          </button>
        ))}
      </div>

      {/* All Events tab filters */}
      {tab === 'all' && (
        <form onSubmit={handleSearch} className="flex flex-wrap gap-3 mb-4">
          <input
            type="text"
            placeholder="Search…"
            value={search}
            onChange={e => setSearch(e.target.value)}
            className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none w-48"
          />
          <select
            value={actionFilter}
            onChange={e => { setActionFilter(e.target.value); setPage(0); }}
            className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none"
          >
            <option value="">All actions</option>
            {Object.entries(ACTION_GROUPS).map(([group, actions]) => (
              <optgroup key={group} label={group}>
                {actions.map(a => <option key={a} value={a}>{a}</option>)}
              </optgroup>
            ))}
          </select>
          <select
            value={severityFilter}
            onChange={e => { setSeverityFilter(e.target.value); setPage(0); }}
            className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none"
          >
            <option value="">All severities</option>
            <option value="info">Info</option>
            <option value="warning">Warning</option>
            <option value="error">Error</option>
            <option value="critical">Critical</option>
          </select>
          <select
            value={successFilter}
            onChange={e => { setSuccessFilter(e.target.value); setPage(0); }}
            className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none"
          >
            <option value="">Success + Failures</option>
            <option value="true">Success only</option>
            <option value="false">Failures only</option>
          </select>
          <button
            type="submit"
            className="px-4 py-1.5 text-sm bg-blue-600 text-white rounded-md hover:bg-blue-700"
          >
            Search
          </button>
          {(search || actionFilter || severityFilter || successFilter) && (
            <button
              type="button"
              onClick={() => { setSearch(''); setActionFilter(''); setSeverityFilter(''); setSuccessFilter(''); setPage(0); }}
              className="px-4 py-1.5 text-sm border border-gray-300 rounded-md text-gray-600 hover:bg-gray-50"
            >
              Clear
            </button>
          )}
        </form>
      )}

      {/* Security tab controls */}
      {tab === 'security' && (
        <div className="flex items-center gap-3 mb-4">
          <label className="text-sm text-gray-600">Last</label>
          <select
            value={securityHours}
            onChange={e => setSecurityHours(Number(e.target.value))}
            className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none"
          >
            <option value={1}>1 hour</option>
            <option value={6}>6 hours</option>
            <option value={24}>24 hours</option>
            <option value={72}>72 hours</option>
          </select>
        </div>
      )}

      {/* User activity tab controls */}
      {tab === 'user' && (
        <div className="flex gap-3 mb-4 items-center">
          <select
            value={activeUserId}
            onChange={e => setActiveUserId(e.target.value)}
            className="px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none w-96"
          >
            <option value="">— Select a user —</option>
            {(usersQuery.data?.users ?? []).map((u: User) => (
              <option key={u.id} value={u.email}>
                {u.full_name ? `${u.full_name} (${u.email})` : u.email}
              </option>
            ))}
          </select>
          {usersQuery.isLoading && (
            <span className="text-sm text-gray-400">Loading users…</span>
          )}
        </div>
      )}

      {/* Results */}
      {tab === 'all' && (
        <>
          {allQuery.data && (
            <p className="text-sm text-gray-500 mb-2">
              {(allQuery.data.total_count ?? 0).toLocaleString()} events total
            </p>
          )}
          <AuditTable logs={allQuery.data?.logs ?? []} isLoading={allQuery.isLoading} />
          {totalPages > 1 && (
            <div className="flex items-center justify-between mt-4">
              <button
                disabled={page === 0}
                onClick={() => setPage(p => p - 1)}
                className="px-4 py-1.5 text-sm border border-gray-300 rounded-md disabled:opacity-40 hover:bg-gray-50"
              >
                Previous
              </button>
              <span className="text-sm text-gray-500">Page {page + 1} of {totalPages}</span>
              <button
                disabled={!allQuery.data?.has_more}
                onClick={() => setPage(p => p + 1)}
                className="px-4 py-1.5 text-sm border border-gray-300 rounded-md disabled:opacity-40 hover:bg-gray-50"
              >
                Next
              </button>
            </div>
          )}
        </>
      )}

      {tab === 'security' && (
        <AuditTable logs={securityQuery.data ?? []} isLoading={securityQuery.isLoading} />
      )}

      {tab === 'user' && (
        activeUserId
          ? <AuditTable logs={userQuery.data ?? []} isLoading={userQuery.isLoading} />
          : <p className="text-gray-500 text-center py-8">Select a user above to view their activity.</p>
      )}
    </div>
  );
}
