'use client';

import { useEffect, useState, useCallback } from 'react';
import { Search, ChevronDown, ScrollText, Download, RefreshCw } from 'lucide-react';
import { cn } from '@/lib/cn';
import { api, ApiError } from '@/lib/api';

interface ApiAuditLog {
  id: string;
  userId: string;
  clubId: string;
  action: string;
  resource: string;
  resourceId: string | null;
  ipAddress: string;
  userAgent: string;
  statusCode: number;
  durationMs: number;
  createdAt: string;
}

interface AuditEntry {
  id: string;
  timestamp: string;
  user: string;
  role: string;
  action: string;
  resource: string;
  resourceId: string;
  ip: string;
  details: string;
  level: 'info' | 'warning' | 'critical';
}

const levelColors: Record<AuditEntry['level'], string> = {
  info: 'bg-blue-100 text-blue-700',
  warning: 'bg-orange-100 text-orange-700',
  critical: 'bg-red-100 text-error',
};
const levelLabels: Record<AuditEntry['level'], string> = { info: 'Инфо', warning: 'Внимание', critical: 'Критично' };

function mapLog(l: ApiAuditLog): AuditEntry {
  const level: AuditEntry['level'] = l.statusCode >= 500 ? 'critical' : l.statusCode >= 400 ? 'warning' : l.action === 'DELETE' ? 'warning' : 'info';
  const statusText = l.statusCode >= 500 ? `Ошибка ${l.statusCode}` : l.statusCode >= 400 ? `Отклонено ${l.statusCode}` : `Успех ${l.statusCode}`;
  const parts = l.resource.split('/').filter((p) => p && p !== 'v1' && !p.match(/^[0-9a-f-]{36}$/i));
  return {
    id: l.id,
    timestamp: new Date(l.createdAt).toLocaleString('ru-RU', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit' }),
    user: l.userId,
    role: l.clubId !== 'unknown' ? `club: ${l.clubId.substring(0, 8)}` : 'platform',
    action: `${l.action} ${parts.join('.')}`,
    resource: l.resource,
    resourceId: l.resourceId || '\u2014',
    ip: l.ipAddress || '\u2014',
    details: `${statusText}, ${l.durationMs} мс`,
    level,
  };
}

function handleExport(entries: AuditEntry[]) {
  const header = 'Время,Уровень,Пользователь,Действие,Ресурс,IP,Описание';
  const escapeField = (val: string) => {
    if (val.includes(',') || val.includes('"') || val.includes('\n')) {
      return `"${val.replace(/"/g, '""')}"`;
    }
    return val;
  };
  const rows = entries.map((e) =>
    [e.timestamp, levelLabels[e.level], e.user, e.action, e.resource, e.ip, e.details]
      .map(escapeField)
      .join(','),
  );
  const csv = '\uFEFF' + [header, ...rows].join('\n');
  const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
  const url = URL.createObjectURL(blob);
  const date = new Date().toISOString().split('T')[0];
  const link = document.createElement('a');
  link.href = url;
  link.download = `audit-log-${date}.csv`;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url);
}

export default function AuditPage() {
  const [entries, setEntries] = useState<AuditEntry[]>([]);
  const [totalCount, setTotalCount] = useState(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [search, setSearch] = useState('');
  const [levelFilter, setLevelFilter] = useState('all');

  const fetchLogs = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const params = new URLSearchParams({ limit: '100' });
      if (search) params.set('search', search);
      if (levelFilter !== 'all') params.set('level', levelFilter);
      const res = await api.get<{ data: ApiAuditLog[]; total: number }>(`/admin/audit-logs?${params}`);
      setEntries(res.data.map(mapLog));
      setTotalCount(res.total);
    } catch (err) {
      if (err instanceof ApiError && err.status === 404) {
        setEntries([]);
        setTotalCount(0);
        setError('Эндпоинт аудит-логов ещё не реализован. Данные появятся после подключения /admin/audit-logs.');
      } else {
        setError(err instanceof Error ? err.message : 'Ошибка загрузки журнала');
      }
    } finally {
      setLoading(false);
    }
  }, [search, levelFilter]);

  useEffect(() => {
    const t = setTimeout(() => void fetchLogs(), 300);
    return () => clearTimeout(t);
  }, [fetchLogs]);

  const filtered = entries.filter((e) => levelFilter === 'all' || e.level === levelFilter);

  if (loading) return <div className="flex items-center justify-center h-64"><div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" /></div>;

  return (
    <div>
      <div className="flex items-center justify-between mb-6">
        <div>
          <h1 className="text-2xl font-bold text-gray-900">Журнал действий</h1>
          <p className="text-sm text-muted mt-1">Аудит всех операций на платформе</p>
        </div>
        <div className="flex items-center gap-3">
          <button onClick={() => void fetchLogs()} className="flex items-center gap-2 border border-border bg-card text-gray-700 px-4 py-2.5 rounded-xl text-sm font-medium hover:bg-background transition-colors">
            <RefreshCw className="h-4 w-4" />Обновить
          </button>
          <button
            onClick={() => handleExport(filtered)}
            disabled={filtered.length === 0}
            className="flex items-center gap-2 border border-border bg-card text-gray-700 px-4 py-2.5 rounded-xl text-sm font-medium hover:bg-background transition-colors disabled:opacity-50"
          >
            <Download className="h-4 w-4" />Экспорт
          </button>
        </div>
      </div>

      {error && <div className="mb-6 px-4 py-3 rounded-lg bg-orange-50 border border-orange-200 text-orange-700 text-sm">{error}</div>}

      <div className="bg-card rounded-xl shadow-sm border border-border">
        <div className="p-4 border-b border-border flex items-center gap-4 flex-wrap">
          <div className="relative flex-1 min-w-[240px]">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted" />
            <input type="text" placeholder="Поиск по действию, пользователю..." value={search} onChange={(e) => setSearch(e.target.value)} className="w-full pl-10 pr-4 py-2 border border-border rounded-lg text-sm bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary" />
          </div>
          <div className="relative">
            <select value={levelFilter} onChange={(e) => setLevelFilter(e.target.value)} className="appearance-none pl-3 pr-8 py-2 border border-border rounded-lg text-sm bg-background focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary">
              <option value="all">Все уровни</option>
              <option value="info">Информационные</option>
              <option value="warning">Предупреждения</option>
              <option value="critical">Критические</option>
            </select>
            <ChevronDown className="absolute right-2 top-1/2 -translate-y-1/2 h-4 w-4 text-muted pointer-events-none" />
          </div>
        </div>

        {filtered.length === 0 && !error ? (
          <div className="flex flex-col items-center justify-center py-16 text-muted">
            <ScrollText className="h-10 w-10 mb-3 opacity-40" />
            <p className="text-sm">Нет записей в журнале</p>
          </div>
        ) : filtered.length > 0 && (
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-border bg-background/50">
                  <th className="text-left px-4 py-3 text-muted font-medium">Время</th>
                  <th className="text-left px-4 py-3 text-muted font-medium">Уровень</th>
                  <th className="text-left px-4 py-3 text-muted font-medium">Пользователь</th>
                  <th className="text-left px-4 py-3 text-muted font-medium">Действие</th>
                  <th className="text-left px-4 py-3 text-muted font-medium">Ресурс</th>
                  <th className="text-left px-4 py-3 text-muted font-medium">IP</th>
                  <th className="text-left px-4 py-3 text-muted font-medium">Описание</th>
                </tr>
              </thead>
              <tbody>
                {filtered.map((e) => (
                  <tr key={e.id} className="border-b border-border/50 hover:bg-background/30 transition-colors">
                    <td className="px-4 py-3 text-xs font-mono text-muted whitespace-nowrap">{e.timestamp}</td>
                    <td className="px-4 py-3"><span className={cn('inline-block px-2 py-0.5 rounded-full text-xs font-medium', levelColors[e.level])}>{levelLabels[e.level]}</span></td>
                    <td className="px-4 py-3"><p className="text-gray-900 text-xs">{e.user}</p><p className="text-muted text-xs">{e.role}</p></td>
                    <td className="px-4 py-3 font-mono text-xs text-gray-700">{e.action}</td>
                    <td className="px-4 py-3"><p className="text-gray-700 text-xs truncate max-w-[200px]">{e.resource}</p><p className="text-muted text-xs font-mono">{e.resourceId}</p></td>
                    <td className="px-4 py-3 font-mono text-xs text-muted">{e.ip}</td>
                    <td className="px-4 py-3 text-xs text-gray-700 max-w-xs truncate">{e.details}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}

        <div className="px-4 py-3 border-t border-border flex items-center justify-between">
          <p className="text-sm text-muted">Показано {filtered.length} из {totalCount} записей</p>
          <div className="flex items-center gap-1">
            <ScrollText className="h-4 w-4 text-muted" />
            <span className="text-xs text-muted">Журнал хранится 90 дней</span>
          </div>
        </div>
      </div>
    </div>
  );
}
