// dashboard/src/features/agent/AuditLogViewer.tsx
import { useState, useEffect } from 'react';
import axios from 'axios';
import { ScrollText, Clock, CheckCircle2, XCircle, AlertTriangle, Loader, ChevronDown, ChevronUp } from 'lucide-react';
import type { AuditLogEntry } from '../../types';

interface AuditLogViewerProps {
  sessionId: string;
  onClose?: () => void;
}

function getToolDisplayName(name: string | null): string {
  if (!name) return '—';
  const map: Record<string, string> = {
    read_file: '读取文件',
    grep_files: '搜索文件',
    glob_files: '匹配文件',
    run_bash: 'Shell 命令',
    file_write: '写入文件',
    file_edit: '编辑文件',
    search_papers: '文献检索',
    get_paper_metadata: '获取元数据',
    download_paper: '下载文献',
    parse_paper: '解析文献',
    get_paper_content: '获取内容',
    rag_search: 'RAG 检索',
    query_target: '天体查询',
    save_note: '保存笔记',
    todo_write: '任务管理',
    compress_context: '压缩上下文',
    load_skill: '加载技能',
    subagent: '派发子代理',
    delegate_research: '子代理研究(旧)',
    ask_user: '用户提问',
    save_memory: '保存记忆',
    load_memory: '读取记忆',
    bg_task_run: '后台任务',
    bg_task_check: '检查后台',
    spawn_teammate: '创建队友',
    send_teammate_message: '队友消息',
    team_broadcast: '团队广播',
    check_team_inbox: '收件箱检查',
  };
  return map[name] || name;
}

export function AuditLogViewer({ sessionId, onClose }: AuditLogViewerProps) {
  const [entries, setEntries] = useState<AuditLogEntry[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [expandedPreview, setExpandedPreview] = useState<Record<number, boolean>>({});

  useEffect(() => {
    if (!sessionId) return;
    setLoading(true);
    setError(null);
    axios
      .get<AuditLogEntry[]>(`/api/chat/sessions/${sessionId}/audit`)
      .then(res => setEntries(res.data))
      .catch(e => {
        console.error('加载审计日志失败:', e);
        setError('审计日志加载失败');
      })
      .finally(() => setLoading(false));
  }, [sessionId]);

  const okCount = entries.filter(e => e.status === 'OK').length;
  const failCount = entries.filter(e => e.status === 'FAIL').length;
  const totalElapsed = entries.reduce((sum, e) => sum + e.elapsed_ms, 0);

  return (
    <div className="space-y-4">
      {/* 头部 */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          <ScrollText className="w-4 h-4 text-sky-600" />
          <h3 className="text-xs font-extrabold text-slate-800 tracking-wide">
            会话审计日志
          </h3>
        </div>
        {onClose && (
          <button
            onClick={onClose}
            className="text-[10px] font-bold text-slate-400 hover:text-slate-600 transition-colors cursor-pointer"
          >
            关闭
          </button>
        )}
      </div>

      {/* 汇总 */}
      {entries.length > 0 && (
        <div className="grid grid-cols-3 gap-2">
          <div className="rounded-lg bg-emerald-50 border border-emerald-200 px-3 py-2 text-center">
            <div className="text-xs font-extrabold text-emerald-700">{okCount}</div>
            <div className="text-[9px] font-bold text-emerald-500">成功</div>
          </div>
          <div className="rounded-lg bg-rose-50 border border-rose-200 px-3 py-2 text-center">
            <div className="text-xs font-extrabold text-rose-700">{failCount}</div>
            <div className="text-[9px] font-bold text-rose-500">失败</div>
          </div>
          <div className="rounded-lg bg-slate-50 border border-slate-200 px-3 py-2 text-center">
            <div className="text-xs font-extrabold text-slate-700">{(totalElapsed / 1000).toFixed(1)}s</div>
            <div className="text-[9px] font-bold text-slate-500">总耗时</div>
          </div>
        </div>
      )}

      {/* 加载/错误状态 */}
      {loading && (
        <div className="flex items-center justify-center py-8 text-slate-400 gap-2">
          <Loader className="w-4 h-4 animate-spin text-sky-600" />
          <span className="text-xs font-bold">加载审计日志中...</span>
        </div>
      )}
      {error && (
        <div className="flex items-center gap-2 text-rose-600 bg-rose-50 border border-rose-200 rounded-lg px-3 py-2 text-xs font-medium">
          <AlertTriangle className="w-3.5 h-3.5" />
          {error}
        </div>
      )}

      {/* 日志表格 */}
      {!loading && entries.length === 0 && !error && (
        <p className="text-xs text-slate-400 italic py-8 text-center">
          该会话暂无审计日志记录
        </p>
      )}

      {entries.length > 0 && (
        <div className="overflow-x-auto">
          <table className="w-full text-[10px]">
            <thead>
              <tr className="border-b border-slate-200 text-left">
                <th className="pb-2 pr-2 font-extrabold text-slate-400 uppercase tracking-wider w-10">步骤</th>
                <th className="pb-2 pr-2 font-extrabold text-slate-400 uppercase tracking-wider">工具</th>
                <th className="pb-2 pr-2 font-extrabold text-slate-400 uppercase tracking-wider w-12">状态</th>
                <th className="pb-2 pr-2 font-extrabold text-slate-400 uppercase tracking-wider w-16 text-right">耗时</th>
                <th className="pb-2 font-extrabold text-slate-400 uppercase tracking-wider">输出预览</th>
              </tr>
            </thead>
            <tbody>
              {entries.map(entry => {
                const isExpanded = expandedPreview[entry.id] || false;
                const hasPreview = entry.output_preview && entry.output_preview.length > 0;

                return (
                  <tr
                    key={entry.id}
                    className={`border-b border-slate-100 ${
                      entry.status === 'FAIL' ? 'bg-rose-50/30' : ''
                    }`}
                  >
                    <td className="py-2 pr-2 font-mono text-slate-500 align-top">
                      #{entry.step}
                    </td>
                    <td className="py-2 pr-2 font-semibold text-slate-700 align-top">
                      {getToolDisplayName(entry.tool_name)}
                      {entry.tool_name && (
                        <span className="text-[9px] text-slate-400 font-mono block">
                          {entry.tool_name}
                        </span>
                      )}
                    </td>
                    <td className="py-2 pr-2 align-top">
                      {entry.status === 'OK' ? (
                        <span className="inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded bg-emerald-100 text-emerald-700 font-bold text-[9px]">
                          <CheckCircle2 className="w-2.5 h-2.5" />
                          OK
                        </span>
                      ) : entry.status === 'FAIL' ? (
                        <span className="inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded bg-rose-100 text-rose-700 font-bold text-[9px]">
                          <XCircle className="w-2.5 h-2.5" />
                          FAIL
                        </span>
                      ) : (
                        <span className="text-slate-400 text-[9px]">{entry.status}</span>
                      )}
                    </td>
                    <td className="py-2 pr-2 text-right font-mono text-slate-500 align-top">
                      <span className="flex items-center gap-0.5 justify-end">
                        <Clock className="w-2.5 h-2.5" />
                        {entry.elapsed_ms >= 1000
                          ? `${(entry.elapsed_ms / 1000).toFixed(1)}s`
                          : `${entry.elapsed_ms}ms`}
                      </span>
                    </td>
                    <td className="py-2 align-top">
                      {hasPreview ? (
                        <div>
                          {isExpanded ? (
                            <div className="space-y-1">
                              <pre className="font-mono text-[9px] text-slate-600 bg-slate-50 border border-slate-200 rounded p-2 max-h-32 overflow-y-auto whitespace-pre-wrap leading-relaxed">
                                {entry.output_preview}
                              </pre>
                              <button
                                onClick={() => setExpandedPreview(prev => ({ ...prev, [entry.id]: false }))}
                                className="text-[9px] font-bold text-sky-600 hover:underline cursor-pointer flex items-center gap-0.5"
                              >
                                <ChevronUp className="w-2.5 h-2.5" />
                                收起
                              </button>
                            </div>
                          ) : (
                            <button
                              onClick={() => setExpandedPreview(prev => ({ ...prev, [entry.id]: true }))}
                              className="text-left font-mono text-[9px] text-slate-500 hover:text-sky-600 transition-colors cursor-pointer flex items-center gap-0.5 max-w-[200px]"
                            >
                              <ChevronDown className="w-2.5 h-2.5 shrink-0" />
                              <span className="truncate">{(entry.output_preview ?? '').slice(0, 60)}{(entry.output_preview ?? '').length > 60 ? '...' : ''}</span>
                            </button>
                          )}
                        </div>
                      ) : (
                        <span className="text-slate-400 italic text-[9px]">—</span>
                      )}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}
