'use client';
import { useState, useEffect, useCallback, useRef } from 'react';
import { auditApi, type AuditEntry } from '@/lib/api-client';

const PAGE_SIZE = 50;

const ACTION_COLORS: Record<string, string> = {
  'admin.mfa.enroll': 'bg-purple-100 text-purple-700',
  'admin.mfa.status': 'bg-purple-100 text-purple-700',
  'admin.mfa.challenge': 'bg-purple-100 text-purple-700',
  'auth.login': 'bg-blue-100 text-blue-700',
  'auth.logout': 'bg-gray-100 text-gray-600',
  'product.created': 'bg-green-100 text-green-700',
  'product.updated': 'bg-green-100 text-green-700',
  'product.deleted': 'bg-red-100 text-red-700',
  'order.placed': 'bg-indigo-100 text-indigo-700',
  'order.state_changed': 'bg-indigo-100 text-indigo-700',
};

function colorForAction(action: string): string {
  return ACTION_COLORS[action] ?? 'bg-gray-100 text-gray-600';
}

export default function AuditLogPage() {
  const [items, setItems] = useState<AuditEntry[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [filter, setFilter] = useState('');
  const [debounced, setDebounced] = useState('');
  const [page, setPage] = useState(0);
  const [total, setTotal] = useState(0);
  const [newCount, setNewCount] = useState(0);
  const [pollingActive, setPollingActive] = useState(false);
  const itemsRef = useRef<AuditEntry[]>([]);

  useEffect(() => {
    const t = setTimeout(() => setDebounced(filter), 400);
    return () => clearTimeout(t);
  }, [filter]);

  useEffect(() => { setPage(0); }, [debounced]);

  const load = useCallback(async () => {
    setLoading(true); setError('');
    try {
      const data = await auditApi.list({ action: debounced || undefined, limit: PAGE_SIZE, offset: page * PAGE_SIZE });
      setItems(data.items ?? []);
      setTotal(data.total ?? 0);
    } catch (e) { setError(e instanceof Error ? e.message : 'Error'); }
    finally { setLoading(false); }
  }, [page, debounced]);

  useEffect(() => { load(); }, [load]);

  // Keep ref in sync with items state for polling deduplication
  useEffect(() => { itemsRef.current = items; }, [items]);

  // Real-time polling: fetch new entries every 5s when on page 0 with no filter
  useEffect(() => {
    if (page !== 0 || debounced) {
      setPollingActive(false);
      return;
    }
    setPollingActive(true);
    const interval = setInterval(async () => {
      try {
        const data = await auditApi.list({ limit: PAGE_SIZE, offset: 0 });
        const existingIds = new Set(itemsRef.current.map(i => i.id));
        const newItems = (data.items ?? []).filter(i => !existingIds.has(i.id));
        if (newItems.length > 0) {
          setItems(prev => [...newItems, ...prev].slice(0, PAGE_SIZE));
          setNewCount(prev => prev + newItems.length);
        }
      } catch { /* silent */ }
    }, 5000);
    return () => { clearInterval(interval); setPollingActive(false); };
  }, [page, debounced]);

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-2xl font-bold text-gray-900">Log de auditoría
          {pollingActive && (
            <span className="ml-3 inline-flex items-center gap-1.5 text-xs text-green-600 font-medium align-middle">
              <span className="inline-block w-2 h-2 rounded-full bg-green-500 animate-pulse" />
              En vivo
            </span>
          )}
          {newCount > 0 && (
            <button
              onClick={() => setNewCount(0)}
              title="Nuevas entradas — haz clic para marcar como vistas"
              className="ml-2 px-2 py-0.5 bg-green-100 text-green-700 text-xs rounded-full hover:bg-green-200 transition-colors"
            >
              +{newCount} nueva{newCount !== 1 ? 's' : ''}
            </button>
          )}
        </h1>
        <p className="text-sm text-gray-500 mt-0.5">
          {total > 0 ? `${total} entrada${total !== 1 ? 's' : ''}` : 'Sin entradas'}
        </p>
      </div>

      <div className="max-w-xs">
        <div className="relative">
          <input type="text" placeholder="Filtrar por acción..." value={filter}
            onChange={e => setFilter(e.target.value)}
            className="w-full pl-10 pr-4 py-2.5 border border-gray-200 rounded-xl text-sm focus:ring-2 focus:ring-[#2D6A4F] outline-none" />
          <span className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400">🔍</span>
        </div>
      </div>

      <div className="bg-white rounded-2xl border border-gray-200 overflow-hidden">
        {loading ? (
          <div className="flex items-center justify-center py-16 text-gray-400 text-sm">Cargando...</div>
        ) : error ? (
          <div className="flex items-center justify-center py-16 text-red-500 text-sm">{error}</div>
        ) : items.length === 0 ? (
          <div className="flex flex-col items-center justify-center py-16 text-gray-400 text-sm gap-2">
            <span className="text-3xl">📋</span><span>Sin entradas de auditoría</span>
          </div>
        ) : (
          <>
            <table className="w-full">
              <thead className="bg-gray-50 border-b border-gray-200">
                <tr>
                  <th className="text-left px-6 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wide">Fecha</th>
                  <th className="text-left px-6 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wide">Acción</th>
                  <th className="text-left px-6 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wide">Objetivo</th>
                  <th className="text-left px-6 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wide">Actor</th>
                  <th className="text-left px-6 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wide">Detalles</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-gray-100">
                {items.map(entry => (
                  <tr key={entry.id} className="hover:bg-gray-50 transition-colors">
                    <td className="px-6 py-4 text-sm text-gray-500 whitespace-nowrap">
                      {new Date(entry.createdAt).toLocaleString('es-ES', { dateStyle: 'short', timeStyle: 'short' })}
                    </td>
                    <td className="px-6 py-4">
                      <span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${colorForAction(entry.action)}`}>
                        {entry.action}
                      </span>
                    </td>
                    <td className="px-6 py-4 text-sm text-gray-600 max-w-xs truncate">{entry.target}</td>
                    <td className="px-6 py-4 text-sm text-gray-400 font-mono">{entry.actorId?.slice(0, 8) ?? '—'}</td>
                    <td className="px-6 py-4 text-xs text-gray-400 font-mono max-w-xs truncate">
                      {Object.keys(entry.metadata ?? {}).length > 0 ? JSON.stringify(entry.metadata) : '—'}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
            {total > PAGE_SIZE && (
              <div className="flex items-center justify-between px-6 py-4 border-t border-gray-200">
                <span className="text-sm text-gray-500">
                  {page * PAGE_SIZE + 1}–{Math.min((page + 1) * PAGE_SIZE, total)} de {total}
                </span>
                <div className="flex gap-2">
                  <button disabled={page === 0} onClick={() => setPage(p => p - 1)}
                    className="px-4 py-2 text-sm border border-gray-300 rounded-xl disabled:opacity-40 hover:bg-gray-50 transition-colors">Anterior</button>
                  <button disabled={(page + 1) * PAGE_SIZE >= total} onClick={() => setPage(p => p + 1)}
                    className="px-4 py-2 text-sm border border-gray-300 rounded-xl disabled:opacity-40 hover:bg-gray-50 transition-colors">Siguiente</button>
                </div>
              </div>
            )}
          </>
        )}
      </div>
    </div>
  );
}
