/**
 * TraceStep — 单个 Trace 步骤
 *
 * 渲染一轮迭代的完整生命周期：Thought + ToolCalls（含状态/结果/耗时）
 */

import { useState, useRef, useEffect } from 'react';
import { Box, Typography, IconButton, Collapse, Stack } from '@mui/material';
import { ChevronDown, ChevronRight, CircleDot, CheckCircle, Loader2, Clock, XCircle, Ban } from 'lucide-react';
import { TRACE_STATE_COLORS, TRACE_STATE_LABELS } from '@renderer/lib/constants';
import { formatDuration, formatTokens } from '@renderer/lib/formatters';
import { toDisplayResult } from '@renderer/lib/tool-result-display';
import type { ToolCallInfo } from '@renderer/stores/agent-store';
import type { TraceStep as TraceStepType } from '@renderer/stores/agent-store';

interface TraceStepProps { step: TraceStepType; isCurrent?: boolean; }

// 工具状态图标
const TOOL_STATUS_ICONS: Record<string, typeof CheckCircle> = {
  pending: Clock,
  executing: Loader2,
  success: CheckCircle,
  error: XCircle,
  blocked: Ban,
};
const TOOL_STATUS_COLORS: Record<string, string> = {
  pending: '#fbbf24',
  executing: '#a855f7',
  success: '#34d399',
  error: '#f87171',
  blocked: '#fb923c',
};
const TOOL_STATUS_LABELS: Record<string, string> = {
  pending: '等待',
  executing: '执行中',
  success: '成功',
  error: '失败',
  blocked: '阻止',
};

export function TraceStep({ step, isCurrent }: TraceStepProps): React.JSX.Element {
  const [expanded, setExpanded] = useState(false);
  const [userTouched, setUserTouched] = useState(false);
  const prevIsCurrentRef = useRef(isCurrent);

  // 仅在 isCurrent 从 false→true 变化时自动展开（新步骤到达）
  // 用户手动操作后不再被自动行为覆盖
  useEffect(() => {
    const wasCurrent = prevIsCurrentRef.current;
    prevIsCurrentRef.current = isCurrent;

    if (isCurrent && !wasCurrent && !userTouched) {
      setExpanded(true);
    } else if (!isCurrent && wasCurrent && !userTouched) {
      setExpanded(false);
    }
  }, [isCurrent, userTouched]);

  const handleToggle = () => {
    setUserTouched(true);
    setExpanded(!expanded);
  };

  const color = TRACE_STATE_COLORS[step.state] ?? '#8b8fa7';
  const label = TRACE_STATE_LABELS[step.state] ?? step.state;
  const duration = step.completedAt ? step.completedAt - step.startedAt : null;

  // 构建状态进度链（如 "思考 → 执行 → 观察"）
  const stateChain = (step.states ?? [step.state])
    .map((s) => TRACE_STATE_LABELS[s] ?? s)
    .join(' → ');

  return (
    <Box sx={{ borderRadius: 1, border: '1px solid', borderColor: 'divider', bgcolor: 'secondary.main', transition: 'all 150ms', ...(isCurrent ? { boxShadow: `0 0 0 1px ${color}` } : {}) }}>
      <IconButton size="small" onClick={handleToggle} sx={{ width: '100%', justifyContent: 'flex-start', gap: 1, px: 1.5, py: 1, borderRadius: '4px 4px 0 0', color: 'text.primary', fontSize: 12 }}>
        {expanded ? <ChevronDown size={10} /> : <ChevronRight size={10} />}
        {isCurrent ? <Loader2 size={12} style={{ color, animation: 'spin 1s linear infinite' }} /> : step.completedAt ? <CheckCircle size={12} style={{ color }} /> : <CircleDot size={12} style={{ color }} />}
        <Typography component="span" sx={{ fontWeight: 600, color, fontSize: 12 }}>#{step.iteration}</Typography>
        <Typography component="span" sx={{ color: 'text.secondary', fontSize: 12 }}>{stateChain}</Typography>
        {duration != null && <Typography variant="caption" sx={{ ml: 'auto', color: 'text.secondary' }}>{formatDuration(duration)}</Typography>}
        {step.tokenUsage && <Typography variant="caption" sx={{ color: 'text.secondary' }}>{formatTokens(step.tokenUsage.totalTokens)} tok</Typography>}
      </IconButton>
      <Collapse in={expanded}>
        <Box sx={{ px: 1.5, pb: 1.5, borderTop: 1, borderColor: 'divider' }}>
          {/* Thought 区域 */}
          {step.thought && (
            <Box sx={{ mt: 1 }}>
              <Typography variant="caption" sx={{ fontWeight: 600, color: 'warning.main', fontSize: 10 }}>💭 Thought</Typography>
              <Box component="pre" sx={{
                fontSize: 11, whiteSpace: 'pre-wrap', color: 'text.secondary',
                fontFamily: "'SF Mono',monospace", m: 0, mt: 0.5,
                maxHeight: 200, overflowY: 'auto',
              }}>
                {step.thought}
              </Box>
            </Box>
          )}

          {/* 工具调用区域 */}
          {step.toolCalls && step.toolCalls.length > 0 && (
            <Box sx={{ mt: 1 }}>
              <Typography variant="caption" sx={{ fontWeight: 600, color: '#a855f7', fontSize: 10 }}>🔧 工具调用</Typography>
              <Stack spacing={0.5} sx={{ mt: 0.5 }}>
                {step.toolCalls.map((tc) => (
                  <ToolCallRow key={tc.id} tc={tc} />
                ))}
              </Stack>
            </Box>
          )}
        </Box>
      </Collapse>
    </Box>
  );
}

/** 工具调用行 — 显示名称、状态、参数、结果摘要、耗时 */
function ToolCallRow({ tc }: { tc: ToolCallInfo }): React.JSX.Element {
  const StatusIcon = TOOL_STATUS_ICONS[tc.status] ?? Clock;
  const statusColor = TOOL_STATUS_COLORS[tc.status] ?? '#8b8fa7';
  const statusLabel = TOOL_STATUS_LABELS[tc.status] ?? tc.status;

  // 结果摘要（限制高度 + 滚动）。渲染前剥离 dataUrl 等超大 base64，避免 ~6.7MB/张进 DOM 导致 OOM
  const hasResult = tc.result != null;
  const displayResult = toDisplayResult(tc.result);
  const resultStr = hasResult
    ? (typeof displayResult === 'string' ? displayResult : JSON.stringify(displayResult, null, 2))
    : '';

  return (
    <Box sx={{ borderRadius: 0.5, border: '1px solid', borderColor: 'divider', borderLeft: `2px solid ${statusColor}`, bgcolor: 'background.default', px: 1, py: 0.5 }}>
      {/* 标题行 */}
      <Stack direction="row" spacing={0.5} sx={{ alignItems: 'center', flexWrap: 'wrap' }}>
        <StatusIcon size={10} style={{ color: statusColor, animation: tc.status === 'executing' ? 'spin 1s linear infinite' : 'none' }} />
        <Typography component="span" sx={{ fontSize: 10, fontWeight: 600, fontFamily: 'monospace', color: 'text.primary' }}>{tc.name}</Typography>
        <Typography component="span" sx={{ fontSize: 9, color: statusColor }}>{statusLabel}</Typography>
        {tc.durationMs != null && (
          <Typography component="span" sx={{ fontSize: 9, color: 'text.secondary', ml: 'auto' }}>{formatDuration(tc.durationMs)}</Typography>
        )}
      </Stack>

      {/* 参数 */}
      {Object.keys(tc.args).length > 0 && (
        <Box component="pre" sx={{
          fontSize: 9, color: 'text.secondary', fontFamily: "'SF Mono',monospace",
          m: 0, mt: 0.25, maxHeight: 60, overflowY: 'auto',
          whiteSpace: 'pre-wrap', wordBreak: 'break-all',
        }}>
          {JSON.stringify(tc.args, null, 2)}
        </Box>
      )}

      {/* 错误信息 */}
      {tc.status === 'error' && tc.error && (
        <Typography sx={{ fontSize: 9, color: 'error.main', mt: 0.25, wordBreak: 'break-word' }}>{tc.error}</Typography>
      )}

      {/* 结果摘要 */}
      {hasResult && (
        <Box component="pre" sx={{
          fontSize: 9, color: 'text.secondary', fontFamily: "'SF Mono',monospace",
          m: 0, mt: 0.25, maxHeight: 80, overflowY: 'auto',
          whiteSpace: 'pre-wrap', wordBreak: 'break-all',
          borderTop: '1px dashed', borderColor: 'divider', pt: 0.25,
        }}>
          {resultStr}
        </Box>
      )}
    </Box>
  );
}
