import { useState, useEffect } from 'react'
import { useParams, useNavigate, useSearchParams } from 'react-router-dom'
import { useQuery } from '@tanstack/react-query'
import {
  ArrowLeft, Folder, FolderOpen, File, FileText, FileCode2,
  Download, Eye, EyeOff, CheckCircle, XCircle, Clock,
  RefreshCw, ChevronRight, ChevronDown, Inbox, AlertCircle,
  Settings2, Info, MousePointerClick,
} from 'lucide-react'
import { agentsApi, type Run, type WorkspaceFile } from '../api/agents'
import { useAppStore } from '../store/app'
import { Spinner } from '../components/ui'
import { clsx } from '../lib/clsx'

// ── helpers ──────────────────────────────────────────────────────

function fmtSize(bytes: number) {
  if (bytes < 1024) return `${bytes} B`
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
  return `${(bytes / 1024 / 1024).toFixed(1)} MB`
}

function fmtMs(ms: number) {
  if (ms < 1000) return `${ms} ms`
  return `${(ms / 1000).toFixed(1)} s`
}

function fmtDate(iso: string) {
  return new Date(iso).toLocaleString('zh-CN', {
    month: 'numeric', day: 'numeric',
    hour: '2-digit', minute: '2-digit', second: '2-digit',
  })
}

function isPreviewable(name: string) {
  return /\.(txt|md|json|jsonl|yaml|yml|py|js|ts|tsx|jsx|sh|log|csv|toml|ini|cfg|xml|html|css|sql|r|rb|go|rs|c|cpp|h|java)$/i.test(name)
}

function fileIcon(name: string) {
  if (/\.(py|js|ts|tsx|jsx|sh|go|rs|c|cpp|h|java|rb|r)$/i.test(name))
    return <FileCode2 size={13} className="text-blue-500 shrink-0" />
  if (/\.(json|jsonl|yaml|yml|toml|ini|cfg|xml)$/i.test(name))
    return <FileText size={13} className="text-yellow-500 shrink-0" />
  if (/\.(md|txt|log|csv|sql)$/i.test(name))
    return <FileText size={13} className="text-gray-400 shrink-0" />
  return <File size={13} className="text-gray-300 shrink-0" />
}

// group flat file list into { dir → files[] } map; root-level files go under ""
function groupFiles(files: WorkspaceFile[]) {
  const map = new Map<string, WorkspaceFile[]>()
  for (const f of files) {
    const slash = f.path.indexOf('/')
    const dir = slash >= 0 ? f.path.slice(0, slash) : ''
    if (!map.has(dir)) map.set(dir, [])
    map.get(dir)!.push(f)
  }
  // sort: root first, then dirs alphabetically
  const sorted = [...map.entries()].sort(([a], [b]) => {
    if (a === '') return -1
    if (b === '') return 1
    return a.localeCompare(b)
  })
  return sorted
}

// ── Run status badge ──────────────────────────────────────────────

function RunBadge({ status }: { status: string }) {
  const cfg: Record<string, { icon: React.ReactNode; cls: string; label: string }> = {
    completed: { icon: <CheckCircle size={11} />, cls: 'text-green-600 bg-green-50', label: '完成' },
    failed:    { icon: <XCircle size={11} />,    cls: 'text-red-600 bg-red-50',      label: '失败' },
    running:   { icon: <RefreshCw size={11} className="animate-spin" />, cls: 'text-blue-600 bg-blue-50', label: '运行中' },
    pending:   { icon: <Clock size={11} />,      cls: 'text-yellow-600 bg-yellow-50', label: '等待' },
  }
  const c = cfg[status] ?? { icon: null, cls: 'text-gray-500 bg-gray-100', label: status }
  return (
    <span className={clsx('inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs font-medium', c.cls)}>
      {c.icon}{c.label}
    </span>
  )
}

// ── File tree (left part of file browser) ────────────────────────

function DirGroup({
  dir, files, selected, onSelect,
}: {
  dir: string
  files: WorkspaceFile[]
  selected: WorkspaceFile | null
  onSelect: (f: WorkspaceFile) => void
}) {
  const [open, setOpen] = useState(true)
  const label = dir || '根目录'
  const isRoot = dir === ''

  return (
    <div>
      {/* Directory header — only show for non-root */}
      {!isRoot && (
        <button
          onClick={() => setOpen(o => !o)}
          className="flex items-center gap-1.5 w-full px-3 py-1.5 text-xs font-semibold text-gray-600 hover:bg-gray-50 transition-colors"
        >
          {open
            ? <FolderOpen size={13} className="text-amber-400 shrink-0" />
            : <Folder size={13} className="text-amber-400 shrink-0" />}
          <span className="font-mono">{label}/</span>
          {open
            ? <ChevronDown size={11} className="ml-auto text-gray-300" />
            : <ChevronRight size={11} className="ml-auto text-gray-300" />}
        </button>
      )}

      {open && (
        <div className={clsx('divide-y divide-gray-50', !isRoot && 'pl-4')}>
          {files.map(f => {
            const baseName = f.path.includes('/') ? f.path.split('/').pop()! : f.path
            const isSelected = selected?.path === f.path
            return (
              <div
                key={f.path}
                onClick={() => onSelect(f)}
                className={clsx(
                  'flex items-center gap-2 px-3 py-1.5 cursor-pointer transition-colors text-xs',
                  isSelected
                    ? 'bg-indigo-50 border-l-2 border-indigo-400'
                    : 'hover:bg-gray-50 border-l-2 border-transparent',
                )}
              >
                {fileIcon(baseName)}
                <span className={clsx('flex-1 font-mono truncate', isSelected ? 'text-indigo-700' : 'text-gray-700')}>
                  {baseName}
                </span>
                <span className="text-gray-400 shrink-0 tabular-nums">{fmtSize(f.size)}</span>
              </div>
            )
          })}
        </div>
      )}
    </div>
  )
}

// ── File preview ──────────────────────────────────────────────────

function FilePreview({
  agentId, runId, file, apiKey,
}: {
  agentId: string
  runId: string
  file: WorkspaceFile
  apiKey: string
}) {
  const [content, setContent] = useState<string | null>(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [shown, setShown] = useState(true)

  useEffect(() => {
    if (!isPreviewable(file.name)) { setContent(null); return }
    if (file.size > 512 * 1024) { setContent(null); return }  // skip > 512 KB
    setContent(null)
    setError(null)
    setLoading(true)
    const url = agentsApi.workspaceDownloadUrl(agentId, runId, file.path)
    fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } })
      .then(r => r.text())
      .then(text => {
        // Try JSON pretty-print
        if (/\.jsonl?$/i.test(file.name)) {
          try { setContent(JSON.stringify(JSON.parse(text), null, 2)) }
          catch { setContent(text) }
        } else {
          setContent(text)
        }
      })
      .catch(e => setError(String(e)))
      .finally(() => setLoading(false))
  }, [agentId, runId, file.path])

  async function download() {
    const url = agentsApi.workspaceDownloadUrl(agentId, runId, file.path)
    const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } })
    if (!res.ok) return
    const blob = await res.blob()
    const a = document.createElement('a')
    a.href = URL.createObjectURL(blob)
    a.download = file.name
    a.click()
    URL.revokeObjectURL(a.href)
  }

  return (
    <div className="flex flex-col h-full">
      {/* Preview header */}
      <div className="flex items-center gap-2 px-4 py-2 border-b border-gray-100 bg-gray-50 shrink-0">
        {fileIcon(file.name)}
        <span className="text-xs font-mono font-medium text-gray-700 flex-1 truncate">{file.path}</span>
        <span className="text-xs text-gray-400">{fmtSize(file.size)}</span>
        {isPreviewable(file.name) && (
          <button
            onClick={() => setShown(s => !s)}
            className="text-gray-400 hover:text-gray-700 transition-colors"
            title={shown ? '收起预览' : '展开预览'}
          >
            {shown ? <EyeOff size={13} /> : <Eye size={13} />}
          </button>
        )}
        <button
          onClick={download}
          className="text-gray-400 hover:text-indigo-600 transition-colors"
          title="下载文件"
        >
          <Download size={13} />
        </button>
      </div>

      {/* Preview content */}
      <div className="flex-1 overflow-auto">
        {loading && (
          <div className="flex items-center gap-2 p-4 text-xs text-gray-400">
            <Spinner size={14} /> 加载预览…
          </div>
        )}
        {error && (
          <div className="flex items-center gap-2 p-4 text-xs text-red-500">
            <AlertCircle size={14} /> {error}
          </div>
        )}
        {!loading && !error && content !== null && shown && (
          <pre className="text-xs font-mono p-4 text-gray-800 whitespace-pre-wrap leading-relaxed">
            {content}
          </pre>
        )}
        {!loading && !error && content === null && (
          <div className="p-6 text-center text-xs text-gray-400">
            {!isPreviewable(file.name)
              ? '二进制文件，不支持预览'
              : file.size > 512 * 1024
                ? `文件过大（${fmtSize(file.size)}），请下载查看`
                : '点击上方眼睛图标展开预览'}
          </div>
        )}
        {!loading && !error && content !== null && !shown && (
          <div className="p-4 text-xs text-gray-400 text-center">已折叠（共 {content.split('\n').length} 行）</div>
        )}
      </div>
    </div>
  )
}

// ── Main page ─────────────────────────────────────────────────────

export default function AgentWorkspace() {
  const { agentId } = useParams<{ agentId: string }>()
  const navigate = useNavigate()
  const [searchParams] = useSearchParams()
  const { apiKey } = useAppStore()

  // ?run=<runId> lets Chat.tsx deep-link directly to a specific run's workspace
  const urlRunId = searchParams.get('run') || null

  const [selectedRunId, setSelectedRunId] = useState<string | null>(urlRunId)
  const [selectedFile, setSelectedFile] = useState<WorkspaceFile | null>(null)

  // Load agent info
  const { data: agent } = useQuery({
    queryKey: ['agents', agentId],
    queryFn: () => agentsApi.get(agentId!),
    enabled: !!agentId,
  })

  // Load run history
  const { data: runsData, isLoading: runsLoading } = useQuery({
    queryKey: ['runs', agentId],
    queryFn: () => agentsApi.runs(agentId!, 100),
    enabled: !!agentId,
    refetchInterval: 10_000,
  })

  const allRuns = runsData?.runs ?? []
  // Auto-select first run with workspace on load (skip if URL already specifies one)
  useEffect(() => {
    if (selectedRunId) return
    const first = allRuns.find(r => r.workspace_path)
    if (first) setSelectedRunId(first.id)
  }, [allRuns, selectedRunId])

  // When URL run param changes (navigation), sync selection
  useEffect(() => {
    if (urlRunId) setSelectedRunId(urlRunId)
  }, [urlRunId])

  // Reset file selection when run changes
  useEffect(() => { setSelectedFile(null) }, [selectedRunId])

  const selectedRun = allRuns.find(r => r.id === selectedRunId) ?? null

  // Load workspace files for selected run
  const { data: wsData, isLoading: wsLoading } = useQuery({
    queryKey: ['workspace', agentId, selectedRunId],
    queryFn: () => agentsApi.workspaceFiles(agentId!, selectedRunId!),
    enabled: !!selectedRunId && !!selectedRun?.workspace_path,
  })

  const files = wsData?.files ?? []
  const groups = groupFiles(files)

  // Derived state
  const hasRuns = allRuns.length > 0
  const hasAnyWorkspace = allRuns.some(r => !!r.workspace_path)

  // Auto-select output.json or first previewable file
  useEffect(() => {
    if (!files.length || selectedFile) return
    const preferred = files.find(f => f.name === 'output.json')
      ?? files.find(f => isPreviewable(f.name))
    if (preferred) setSelectedFile(preferred)
  }, [files])

  return (
    <div className="flex flex-col h-screen bg-gray-50">
      {/* Header */}
      <div className="flex items-center gap-3 px-6 py-4 bg-white border-b border-gray-200 shrink-0">
        <button onClick={() => navigate('/agents')} className="text-gray-400 hover:text-gray-700 transition-colors">
          <ArrowLeft size={18} />
        </button>
        <div className="flex items-center gap-2">
          <Folder size={16} className="text-amber-500" />
          <span className="text-sm font-semibold text-gray-900">
            {agent?.name ?? '…'} 的工作区
          </span>
        </div>
        <span className="text-xs text-gray-400 ml-1">
          {allRuns.length} 次运行 · {allRuns.filter(r => r.workspace_path).length} 个工作区
        </span>
      </div>

      {/* Body */}
      <div className="flex flex-1 overflow-hidden">

        {/* ── Run list sidebar ─────────────────────────────── */}
        <div className="w-64 shrink-0 border-r border-gray-200 bg-white flex flex-col overflow-hidden">
          <div className="px-4 py-2.5 border-b border-gray-100 shrink-0">
            <p className="text-xs font-semibold text-gray-500 uppercase tracking-wide">运行记录</p>
          </div>

          <div className="flex-1 overflow-y-auto">
            {runsLoading && (
              <div className="flex justify-center py-8"><Spinner size={20} /></div>
            )}
            {!runsLoading && allRuns.length === 0 && (
              <div className="text-center py-12 px-4">
                <Inbox size={28} className="mx-auto mb-2 text-gray-300" />
                <p className="text-xs text-gray-400">暂无运行记录</p>
                <p className="text-xs text-gray-300 mt-1">先在对话页发送消息</p>
              </div>
            )}
            {/* Banner: runs exist but none have workspace */}
            {!runsLoading && hasRuns && !hasAnyWorkspace && (
              agent?.agent_dir ? (
                /* agent_dir set — just needs a fresh run */
                <div className="mx-3 mt-3 rounded-lg border border-green-200 bg-green-50 p-3 text-xs text-green-700 space-y-1.5">
                  <div className="flex items-center gap-1.5 font-semibold">
                    <CheckCircle size={12} /> 工作目录已配置
                  </div>
                  <p className="leading-relaxed text-green-600">
                    发送一条新消息后，工作区文件将自动出现。
                  </p>
                  <button
                    onClick={() => navigate(`/chat/${agentId}`)}
                    className="flex items-center gap-1 font-medium text-green-700 hover:text-green-900 transition-colors"
                  >
                    <MousePointerClick size={11} /> 去对话页 →
                  </button>
                </div>
              ) : (
                /* agent_dir not set — need to configure */
                <div className="mx-3 mt-3 rounded-lg border border-amber-200 bg-amber-50 p-3 text-xs text-amber-700 space-y-1.5">
                  <div className="flex items-center gap-1.5 font-semibold">
                    <AlertCircle size={12} /> 未设置工作目录
                  </div>
                  <p className="leading-relaxed text-amber-600">
                    在编辑页的「基本设置」中填写工作目录后重新运行即可。
                  </p>
                  <button
                    onClick={() => navigate(`/agents/${agentId}/edit`)}
                    className="flex items-center gap-1 font-medium text-amber-700 hover:text-amber-900 transition-colors"
                  >
                    <Settings2 size={11} /> 去设置 →
                  </button>
                </div>
              )
            )}
            {allRuns.map(run => {
              const hasWS = !!run.workspace_path
              const isSelected = run.id === selectedRunId
              return (
                <button
                  key={run.id}
                  onClick={() => hasWS && setSelectedRunId(run.id)}
                  disabled={!hasWS}
                  className={clsx(
                    'w-full text-left px-4 py-3 border-b border-gray-50 transition-colors',
                    isSelected
                      ? 'bg-indigo-50 border-l-2 border-indigo-400'
                      : 'hover:bg-gray-50 border-l-2 border-transparent',
                    !hasWS && 'opacity-40 cursor-default',
                  )}
                >
                  <div className="flex items-center gap-2 mb-1">
                    <RunBadge status={run.status} />
                    {run.duration_ms > 0 && (
                      <span className="text-xs text-gray-400 ml-auto">{fmtMs(run.duration_ms)}</span>
                    )}
                  </div>
                  <p className="text-xs text-gray-500 mb-0.5">{fmtDate(run.created_at)}</p>
                  {run.input && (
                    <p className="text-xs text-gray-400 truncate leading-relaxed">
                      {run.input.slice(0, 50)}
                    </p>
                  )}
                  {run.input_tokens > 0 && (
                    <p className="text-xs text-gray-300 mt-0.5">{run.input_tokens} tokens</p>
                  )}
                  {!hasWS && (
                    <p className="text-xs text-gray-300 italic mt-0.5">无工作区</p>
                  )}
                </button>
              )
            })}
          </div>
        </div>

        {/* ── No workspace runs yet ─── */}
        {!runsLoading && hasRuns && !hasAnyWorkspace && (
          <div className="flex-1 flex items-center justify-center bg-gray-50 p-8">
            <div className="max-w-md w-full space-y-6">

              {agent?.agent_dir ? (
                /* ── Case A: agent_dir IS set, just no runs with workspace yet ── */
                <>
                  <div className="text-center">
                    <div className="w-14 h-14 rounded-2xl bg-green-50 border border-green-200 flex items-center justify-center mx-auto mb-4">
                      <CheckCircle size={28} className="text-green-500" />
                    </div>
                    <h2 className="text-base font-semibold text-gray-800">工作目录已配置</h2>
                    <p className="text-sm text-gray-500 mt-1">
                      历史运行均在配置工作目录之前产生，因此没有工作区文件。
                      <br />下次运行会自动生成。
                    </p>
                  </div>

                  <div className="rounded-xl border border-gray-200 bg-white p-4 space-y-3">
                    <p className="text-xs font-semibold text-gray-500 uppercase tracking-wide">当前工作目录</p>
                    <code className="block text-xs bg-gray-50 border border-gray-200 rounded-lg px-3 py-2.5 font-mono text-indigo-600 break-all">
                      {agent.agent_dir}
                    </code>
                    <p className="text-xs text-gray-400 leading-relaxed">
                      每次运行会在此目录下自动创建：
                      <br /><span className="font-mono text-gray-500">workspace/run_YYYYMMDD_HHMMSS/</span>
                    </p>
                  </div>

                  <div className="flex gap-3 justify-center">
                    <button
                      onClick={() => navigate(`/chat/${agentId}`)}
                      className="flex items-center gap-2 px-5 py-2.5 rounded-lg bg-indigo-600 text-white text-sm font-medium hover:bg-indigo-700 transition-colors shadow-sm"
                    >
                      <MousePointerClick size={14} />
                      去对话页发消息
                    </button>
                    <button
                      onClick={() => navigate(`/agents/${agentId}/edit`)}
                      className="flex items-center gap-2 px-4 py-2.5 rounded-lg border border-gray-200 bg-white text-gray-600 text-sm font-medium hover:bg-gray-50 transition-colors"
                    >
                      <Settings2 size={14} />
                      修改路径
                    </button>
                  </div>
                </>
              ) : (
                /* ── Case B: agent_dir NOT set — full setup guide ── */
                <>
                  <div className="text-center">
                    <div className="w-14 h-14 rounded-2xl bg-amber-50 border border-amber-200 flex items-center justify-center mx-auto mb-4">
                      <Folder size={28} className="text-amber-400" />
                    </div>
                    <h2 className="text-base font-semibold text-gray-800">工作区未启用</h2>
                    <p className="text-sm text-gray-500 mt-1">
                      为智能体设置工作目录后，每次运行的输入、输出、推理轨迹和产物文件都会被持久化保存。
                    </p>
                  </div>

                  <div className="rounded-xl border border-gray-200 bg-white divide-y divide-gray-100">
                    <div className="flex gap-3 p-4">
                      <span className="w-5 h-5 rounded-full bg-indigo-100 text-indigo-600 text-xs font-bold flex items-center justify-center shrink-0 mt-0.5">1</span>
                      <div>
                        <p className="text-sm font-medium text-gray-700">设置工作目录</p>
                        <p className="text-xs text-gray-500 mt-0.5">
                          点击下方按钮 → 编辑 → 基本设置 → <span className="font-mono bg-gray-100 px-1 rounded">工作目录（agent_dir）</span> 填入本地路径，例如：
                        </p>
                        <code className="block mt-1.5 text-xs bg-gray-50 border border-gray-200 rounded-lg px-3 py-2 font-mono text-gray-600">
                          /home/user/my-agent
                        </code>
                      </div>
                    </div>
                    <div className="flex gap-3 p-4">
                      <span className="w-5 h-5 rounded-full bg-indigo-100 text-indigo-600 text-xs font-bold flex items-center justify-center shrink-0 mt-0.5">2</span>
                      <div>
                        <p className="text-sm font-medium text-gray-700">保存并重新运行</p>
                        <p className="text-xs text-gray-500 mt-0.5">
                          保存后，在对话页发送一条消息，系统会自动在工作目录下创建：
                        </p>
                        <code className="block mt-1.5 text-xs bg-gray-50 border border-gray-200 rounded-lg px-3 py-2 font-mono text-gray-600 leading-relaxed">
                          workspace/run_20260602_224935/<br />
                          {'├── input.json  ├── output.json'}<br />
                          {'├── trace.json  └── cost.json'}
                        </code>
                      </div>
                    </div>
                    <div className="flex gap-3 p-4">
                      <span className="w-5 h-5 rounded-full bg-indigo-100 text-indigo-600 text-xs font-bold flex items-center justify-center shrink-0 mt-0.5">3</span>
                      <div>
                        <p className="text-sm font-medium text-gray-700">回到此页查看</p>
                        <p className="text-xs text-gray-500 mt-0.5">
                          左栏选运行记录 → 中栏点文件 → 右栏即时预览，支持 JSON 格式化，可下载。
                        </p>
                      </div>
                    </div>
                  </div>

                  <div className="flex justify-center">
                    <button
                      onClick={() => navigate(`/agents/${agentId}/edit`)}
                      className="flex items-center gap-2 px-5 py-2.5 rounded-lg bg-indigo-600 text-white text-sm font-medium hover:bg-indigo-700 transition-colors shadow-sm"
                    >
                      <Settings2 size={14} />
                      去设置工作目录
                    </button>
                  </div>
                </>
              )}
            </div>
          </div>
        )}

        {/* ── File browser + preview (only when workspaces exist) ── */}
        {(hasAnyWorkspace || !hasRuns) && (
        <div className="flex flex-1 overflow-hidden">

          {/* File tree */}
          <div className="w-60 shrink-0 border-r border-gray-200 bg-white flex flex-col overflow-hidden">
            <div className="px-4 py-2.5 border-b border-gray-100 shrink-0 flex items-center gap-2">
              <p className="text-xs font-semibold text-gray-500 uppercase tracking-wide flex-1">文件</p>
              {wsData && (
                <span className="text-xs text-gray-400">{files.length} 个</span>
              )}
            </div>

            <div className="flex-1 overflow-y-auto">
              {!selectedRunId && (
                <div className="text-center py-12 px-4">
                  <Folder size={28} className="mx-auto mb-2 text-gray-200" />
                  <p className="text-xs text-gray-400">选择左侧运行记录</p>
                </div>
              )}
              {selectedRunId && !selectedRun?.workspace_path && (
                <div className="text-center py-12 px-4">
                  <AlertCircle size={28} className="mx-auto mb-2 text-gray-200" />
                  <p className="text-xs text-gray-400">该次运行无工作区</p>
                </div>
              )}
              {wsLoading && (
                <div className="flex justify-center py-8"><Spinner size={20} /></div>
              )}
              {!wsLoading && files.length === 0 && selectedRun?.workspace_path && (
                <div className="text-center py-12 px-4">
                  <Inbox size={28} className="mx-auto mb-2 text-gray-200" />
                  <p className="text-xs text-gray-400">工作区为空</p>
                </div>
              )}
              {groups.map(([dir, dirFiles]) => (
                <DirGroup
                  key={dir}
                  dir={dir}
                  files={dirFiles}
                  selected={selectedFile}
                  onSelect={setSelectedFile}
                />
              ))}
            </div>
          </div>

          {/* Preview area */}
          <div className="flex-1 bg-white overflow-hidden flex flex-col">
            {!selectedFile ? (
              <div className="flex flex-col items-center justify-center h-full gap-6 px-8">
                {/* How-to hint when workspace files are available */}
                {hasAnyWorkspace && selectedRunId && files.length > 0 ? (
                  <div className="text-center">
                    <MousePointerClick size={36} className="mx-auto mb-3 text-gray-200" />
                    <p className="text-sm text-gray-400">点击左侧文件名即可预览</p>
                    <p className="text-xs text-gray-300 mt-1">支持 JSON / 代码 / 文本，右上角可下载</p>
                  </div>
                ) : hasAnyWorkspace ? (
                  <div className="text-center">
                    <Folder size={36} className="mx-auto mb-3 text-amber-200" />
                    <p className="text-sm text-gray-400">点击左侧有工作区的运行记录</p>
                    <p className="text-xs text-gray-300 mt-1">只有标记了"完成"的运行才有文件</p>
                  </div>
                ) : (
                  <div className="text-center">
                    <Eye size={36} className="mx-auto mb-3 text-gray-200" />
                    <p className="text-sm text-gray-400">暂无可预览的文件</p>
                  </div>
                )}

                {/* Inline usage guide */}
                {hasAnyWorkspace && (
                  <div className="w-full max-w-sm rounded-xl border border-gray-100 bg-gray-50 p-4 space-y-3">
                    <div className="flex items-center gap-2 text-xs font-semibold text-gray-500">
                      <Info size={12} /> 工作区文件说明
                    </div>
                    <div className="space-y-2 text-xs text-gray-500">
                      {[
                        ['input.json',  '本次运行的原始输入和时间戳'],
                        ['output.json', '最终回答、状态码、耗时统计'],
                        ['trace.json',  '完整推理轨迹（每个工具调用和结果）'],
                        ['cost.json',   'Token 用量和估算费用'],
                        ['config.yml',  '本次运行时使用的配置快照'],
                        ['code/',       'Agent 产生的代码文件'],
                        ['results/',    'Agent 产生的数据或分析结果'],
                        ['final/',      '最终输出产物'],
                      ].map(([name, desc]) => (
                        <div key={name} className="flex gap-2">
                          <code className="font-mono text-indigo-500 shrink-0 w-24">{name}</code>
                          <span className="text-gray-400">{desc}</span>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            ) : (
              <>
                {/* Run context bar */}
                {selectedRun && (
                  <div className="flex items-center gap-3 px-4 py-2 bg-gray-50 border-b border-gray-100 text-xs text-gray-500 shrink-0">
                    <RunBadge status={selectedRun.status} />
                    <span>{fmtDate(selectedRun.created_at)}</span>
                    {selectedRun.duration_ms > 0 && <span>{fmtMs(selectedRun.duration_ms)}</span>}
                    {selectedRun.steps > 0 && <span>{selectedRun.steps} 步</span>}
                    {selectedRun.input_tokens > 0 && <span>{selectedRun.input_tokens} tokens</span>}
                  </div>
                )}
                <div className="flex-1 overflow-hidden">
                  <FilePreview
                    agentId={agentId!}
                    runId={selectedRunId!}
                    file={selectedFile}
                    apiKey={apiKey ?? ''}
                  />
                </div>
              </>
            )}
          </div>
        </div>
        )}
      </div>
    </div>
  )
}
