'use client';

import { useCallback, useEffect, useState } from 'react';
import { motion } from 'framer-motion';
import { FileText, Loader2 } from 'lucide-react';
import { getResponseErrorTextWithRequestId } from '@/lib/api-client';
import { cn, formatDateTime, getAuditMeta } from '@/lib/admin/utils';
import type { AuditEntry } from '@/lib/types/admin';

type AuditTabProps = {
  isAdmin: boolean;
  setErrorMessage: (message: string) => void;
};

export function AuditTab({ isAdmin, setErrorMessage }: AuditTabProps) {
  const [auditEntries, setAuditEntries] = useState<AuditEntry[]>([]);
  const [isAuditLoading, setIsAuditLoading] = useState(false);
  const [auditLoaded, setAuditLoaded] = useState(false);

  const getApiErrorText = useCallback(async (response: Response, fallback: string) => {
    return getResponseErrorTextWithRequestId(response, fallback);
  }, []);

  const fetchAuditLog = useCallback(async () => {
    if (!isAdmin) return;
    setIsAuditLoading(true);

    try {
      const response = await fetch('/api/admin/audit-log?limit=100', { cache: 'no-store' });
      if (!response.ok) {
        throw new Error(await getApiErrorText(response, 'Не удалось загрузить журнал действий'));
      }
      const data = await response.json() as { entries?: AuditEntry[] };
      setAuditEntries(data.entries ?? []);
      setAuditLoaded(true);
      setErrorMessage('');
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : 'Не удалось загрузить журнал действий');
    } finally {
      setIsAuditLoading(false);
    }
  }, [getApiErrorText, isAdmin, setErrorMessage]);

  useEffect(() => {
    if (!isAdmin) return;
    void fetchAuditLog();
  }, [fetchAuditLog, isAdmin]);

  return (
    <motion.div key="audit" initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -10 }} className="space-y-6 max-w-5xl mx-auto pb-10">
      {!isAdmin ? (
        <div className="rounded-2xl border border-white/10 bg-white/[0.02] p-6 text-sm text-gray-300">
          Журнал действий доступен только администратору.
        </div>
      ) : (
        <>
          <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
            <div>
              <h2 className="text-2xl font-bold flex items-center gap-3">
                <div className="p-2.5 bg-violet-500/10 rounded-xl border border-violet-500/20">
                  <FileText className="w-6 h-6 text-violet-400" />
                </div>
                Журнал действий
              </h2>
              <p className="text-sm text-gray-400 mt-2 max-w-2xl">
                Последние действия администраторов и модераторов в панели управления.
                Показаны последние 100 записей.
              </p>
            </div>
            <button
              type="button"
              onClick={() => void fetchAuditLog()}
              disabled={isAuditLoading}
              className="inline-flex items-center gap-2 px-4 py-2.5 rounded-xl border border-white/10 bg-white/[0.03] hover:bg-white/[0.06] text-sm font-medium text-gray-200 transition-colors disabled:opacity-60 shrink-0"
            >
              {isAuditLoading ? (
                <>
                  <Loader2 className="w-4 h-4 animate-spin" />
                  Обновление...
                </>
              ) : 'Обновить'}
            </button>
          </div>

          {isAuditLoading && !auditLoaded ? (
            <div className="rounded-3xl border border-white/5 bg-[#0A0A0A] p-10 text-center text-sm text-gray-400">
              <Loader2 className="w-5 h-5 animate-spin text-violet-400 mx-auto mb-3" />
              Загружаем журнал...
            </div>
          ) : auditEntries.length === 0 ? (
            <div className="rounded-3xl border border-white/5 bg-[#0A0A0A] p-10 text-center">
              <FileText className="w-10 h-10 text-gray-500 mx-auto mb-3" />
              <h3 className="text-lg font-bold text-white">Журнал пуст</h3>
              <p className="text-sm text-gray-400 mt-2">Здесь появятся записи о действиях после того, как они будут выполнены.</p>
            </div>
          ) : (
            <div className="bg-[#0A0A0A] border border-white/5 rounded-3xl shadow-xl overflow-hidden">
              <div className="divide-y divide-white/5">
                {auditEntries.map((entry) => {
                  const meta = getAuditMeta(entry.action);
                  const metaJson = entry.metadata
                    ? JSON.stringify(entry.metadata, null, 2)
                    : null;
                  return (
                    <div key={entry.id} className="p-5 hover:bg-white/[0.02] transition-colors">
                      <div className="flex flex-wrap items-start gap-3">
                        <span className={cn('inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg border text-[11px] font-bold uppercase tracking-wider shrink-0', meta.bg, meta.color)}>
                          {meta.label}
                        </span>
                        <div className="flex-1 min-w-0">
                          <div className="flex flex-wrap items-center gap-2 text-sm">
                            <span className="text-gray-400">{entry.actorLabel || '—'}</span>
                            {entry.actorRole ? (
                              <span className="text-[10px] font-mono uppercase tracking-wider text-gray-500 bg-white/5 px-2 py-0.5 rounded border border-white/5">
                                {entry.actorRole}
                              </span>
                            ) : null}
                            <span className="text-gray-600">→</span>
                            <span className="text-white font-medium">
                              {entry.targetLabel || entry.targetId || '—'}
                            </span>
                            {entry.targetType ? (
                              <span className="text-[10px] font-mono uppercase tracking-wider text-gray-500">
                                {entry.targetType}
                              </span>
                            ) : null}
                          </div>
                          {metaJson ? (
                            <pre className="mt-2 text-[11px] text-gray-500 font-mono bg-black/40 px-3 py-2 rounded-lg border border-white/5 overflow-x-auto whitespace-pre-wrap break-words max-h-40">
                              {metaJson}
                            </pre>
                          ) : null}
                        </div>
                        <span className="text-xs font-mono text-gray-500 bg-black/40 px-3 py-1.5 rounded-lg border border-white/5 shrink-0">
                          {formatDateTime(entry.createdAt)}
                        </span>
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          )}
        </>
      )}
    </motion.div>
  );
}
