import { useEffect, useMemo, useState } from 'react';
import {
  ApartmentOutlined,
  ClockCircleOutlined,
  PlayCircleOutlined,
  PlusOutlined,
  ThunderboltOutlined
} from '@ant-design/icons';
import {
  Button,
  Card,
  Drawer,
  Empty,
  Form,
  Input,
  Modal,
  Select,
  Space,
  Switch,
  Table,
  Tag,
  Tooltip,
  Typography,
  App as AntApp,
  Popconfirm,
  Tabs
} from 'antd';
import {
  Workflow,
  WorkflowAPI,
  WorkflowGraph,
  WorkflowNode,
  WorkflowNodeType,
  WorkflowRun,
  WorkflowRunDetail,
  streamWorkflowRun
} from '../api';

const { Text, Paragraph } = Typography;

const NODE_TYPE_LABEL: Record<WorkflowNodeType, string> = {
  agent: '🤖 Agent',
  skill: '🛠️ Skill',
  http: '🌐 HTTP',
  transform: '🔧 Transform',
  branch: '🔀 Branch'
};

const STATUS_COLOR: Record<string, string> = {
  running: 'blue',
  success: 'green',
  failed: 'red',
  aborted: 'orange',
  skipped: 'default'
};

const SAMPLE_GRAPH: WorkflowGraph = {
  entry: 'fetch',
  variables: { topic: 'Go 1.23 新特性' },
  nodes: [
    {
      id: 'fetch',
      type: 'agent',
      name: '搜集资料',
      config: {
        agentId: '',
        prompt: '请围绕主题"{{vars.topic}}"列出 5 条最近的关键信息，要点形式。'
      },
      next: 'summarize'
    },
    {
      id: 'summarize',
      type: 'agent',
      name: '总结成稿',
      config: {
        agentId: '',
        prompt: '基于以下要点写一段 200 字日报：\n{{steps.fetch.output.text}}'
      },
      next: ''
    }
  ]
};

export default function WorkflowsPage() {
  const { message, modal } = AntApp.useApp();
  const [list, setList] = useState<Workflow[]>([]);
  const [loading, setLoading] = useState(false);
  const [editorOpen, setEditorOpen] = useState(false);
  const [editing, setEditing] = useState<Workflow | null>(null);
  const [runsOpen, setRunsOpen] = useState(false);
  const [runsFor, setRunsFor] = useState<Workflow | null>(null);

  const load = async () => {
    setLoading(true);
    try {
      const data = await WorkflowAPI.list();
      setList(data);
    } catch (e: any) {
      message.error('加载失败：' + (e?.message ?? e));
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    load();
  }, []);

  const onCreate = () => {
    setEditing({
      id: '',
      name: '新工作流',
      description: '',
      graph: SAMPLE_GRAPH,
      scheduleCron: '',
      scheduleEnabled: false,
      enabled: true,
      lastRunAt: 0,
      runCount: 0,
      createdAt: 0,
      updatedAt: 0
    });
    setEditorOpen(true);
  };

  const onEdit = (w: Workflow) => {
    setEditing(w);
    setEditorOpen(true);
  };

  const onDelete = async (w: Workflow) => {
    await WorkflowAPI.remove(w.id);
    message.success('已删除');
    load();
  };

  return (
    <div className="page-container" style={{ maxWidth: 1400 }}>
      <div
        style={{
          borderRadius: 24,
          padding: '30px 30px 26px',
          background:
            'linear-gradient(135deg, rgba(255,255,255,0.98) 0%, rgba(236,253,245,0.92) 42%, rgba(239,246,255,0.96) 100%)',
          border: '1px solid rgba(8, 145, 178, 0.12)',
          boxShadow: '0 20px 48px rgba(15, 23, 42, 0.06)',
          marginBottom: 24
        }}
      >
        <div
          style={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'flex-start',
            gap: 20,
            flexWrap: 'wrap',
            marginBottom: 20
          }}
        >
          <div style={{ maxWidth: 680 }}>
            <div
              style={{
                display: 'inline-flex',
                alignItems: 'center',
                gap: 8,
                padding: '6px 12px',
                borderRadius: 999,
                background: 'rgba(255,255,255,0.78)',
                border: '1px solid rgba(8, 145, 178, 0.10)',
                color: 'var(--color-text-secondary)',
                fontSize: 12,
                fontWeight: 600,
                marginBottom: 16
              }}
            >
              <ApartmentOutlined style={{ color: 'var(--color-brand)' }} />
              自动化编排中心
            </div>
            <h1 className="page-title" style={{ marginBottom: 10 }}>工作流编排</h1>
            <div className="page-subtitle" style={{ marginTop: 0, fontSize: 15, lineHeight: 1.75 }}>
              让多个 Agent、技能、HTTP 请求与数据转换连成一条可运行的自动化链路。这里更像一个流程画廊，而不是传统表格后台。
            </div>
          </div>
          <Button
            type="primary"
            size="large"
            icon={<PlusOutlined />}
            onClick={onCreate}
            style={{ borderRadius: 14, height: 46, padding: '0 18px', fontWeight: 600 }}
          >
            新建工作流
          </Button>
        </div>

        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, minmax(0, 1fr))', gap: 14 }}>
          {[
            { label: '工作流数量', value: list.length, tone: 'rgba(8, 145, 178, 0.10)', color: 'var(--color-brand)' },
            { label: '启用中', value: list.filter((item) => item.enabled).length, tone: 'rgba(34, 197, 94, 0.10)', color: 'var(--color-success)' },
            { label: '定时运行', value: list.filter((item) => item.scheduleEnabled && item.scheduleCron).length, tone: 'rgba(249, 115, 22, 0.10)', color: 'var(--color-warning)' }
          ].map((item) => (
            <div
              key={item.label}
              style={{
                borderRadius: 18,
                padding: '16px 18px',
                background: 'rgba(255,255,255,0.72)',
                border: '1px solid rgba(255,255,255,0.7)'
              }}
            >
              <div style={{ fontSize: 12.5, color: 'var(--color-text-secondary)', marginBottom: 10 }}>{item.label}</div>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
                <span style={{ fontSize: 30, fontWeight: 700, color: 'var(--color-text)' }}>{item.value}</span>
                <span
                  style={{
                    borderRadius: 999,
                    padding: '4px 8px',
                    background: item.tone,
                    color: item.color,
                    fontSize: 12,
                    fontWeight: 600
                  }}
                >
                  实时状态
                </span>
              </div>
            </div>
          ))}
        </div>
      </div>

      {loading ? null : list.length === 0 ? (
        <div
          style={{
            borderRadius: 22,
            background: 'var(--color-surface)',
            border: '1px solid var(--color-border)',
            padding: '54px 24px'
          }}
        >
          <Empty description="还没有工作流，点击上方开始搭建第一条自动化流程" />
        </div>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(340px, 1fr))', gap: 18 }}>
          {list.map((r) => (
            <div
              key={r.id}
              style={{
                borderRadius: 20,
                border: '1px solid var(--color-border)',
                background: 'linear-gradient(180deg, rgba(255,255,255,0.98) 0%, rgba(252,252,253,1) 100%)',
                boxShadow: '0 12px 28px rgba(15, 23, 42, 0.045)',
                padding: 20,
                minHeight: 308,
                display: 'flex',
                flexDirection: 'column'
              }}
            >
              <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, marginBottom: 16 }}>
                <div style={{ minWidth: 0 }}>
                  <div style={{ fontSize: 19, fontWeight: 700, color: 'var(--color-text)', marginBottom: 6 }}>{r.name}</div>
                  <div style={{ fontSize: 13, color: 'var(--color-text-secondary)', lineHeight: 1.7 }}>
                    {r.description || '还没有补充描述，可以说明这个流程负责什么自动化任务。'}
                  </div>
                </div>
                <Tag
                  bordered={false}
                  style={{
                    margin: 0,
                    borderRadius: 999,
                    background: r.enabled ? 'var(--color-success-soft)' : 'var(--color-surface-2)',
                    color: r.enabled ? 'var(--color-success)' : 'var(--color-text-secondary)',
                    height: 28,
                    lineHeight: '28px'
                  }}
                >
                  {r.enabled ? '已启用' : '已停用'}
                </Tag>
              </div>

              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, minmax(0, 1fr))', gap: 12, marginBottom: 16 }}>
                <div style={{ borderRadius: 16, padding: '14px 14px 12px', background: 'rgba(8, 145, 178, 0.06)', border: '1px solid rgba(8, 145, 178, 0.10)' }}>
                  <div style={{ fontSize: 12, color: 'var(--color-text-secondary)', marginBottom: 8 }}>节点数</div>
                  <div style={{ fontSize: 24, fontWeight: 700, color: 'var(--color-text)' }}>{r.graph?.nodes?.length ?? 0}</div>
                </div>
                <div style={{ borderRadius: 16, padding: '14px 14px 12px', background: 'rgba(34, 197, 94, 0.06)', border: '1px solid rgba(34, 197, 94, 0.10)' }}>
                  <div style={{ fontSize: 12, color: 'var(--color-text-secondary)', marginBottom: 8 }}>运行次数</div>
                  <div style={{ fontSize: 24, fontWeight: 700, color: 'var(--color-text)' }}>{r.runCount}</div>
                </div>
                <div style={{ borderRadius: 16, padding: '14px 14px 12px', background: 'rgba(249, 115, 22, 0.06)', border: '1px solid rgba(249, 115, 22, 0.10)' }}>
                  <div style={{ fontSize: 12, color: 'var(--color-text-secondary)', marginBottom: 8 }}>触发方式</div>
                  <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--color-text)' }}>
                    {r.scheduleEnabled && r.scheduleCron ? '定时' : '手动'}
                  </div>
                </div>
              </div>

              <div
                style={{
                  borderRadius: 16,
                  padding: '16px 16px 14px',
                  background: 'linear-gradient(180deg, rgba(248,250,252,0.9) 0%, rgba(255,255,255,0.95) 100%)',
                  border: '1px solid rgba(148, 163, 184, 0.14)',
                  marginBottom: 16
                }}
              >
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 12.5, color: 'var(--color-text-secondary)', marginBottom: 10 }}>
                  <ClockCircleOutlined />
                  调度与运行
                </div>
                {r.scheduleEnabled && r.scheduleCron ? (
                  <Tag bordered={false} style={{ margin: 0, background: 'var(--color-brand-soft)', color: 'var(--color-brand)', borderRadius: 999 }}>
                    cron: {r.scheduleCron}
                  </Tag>
                ) : (
                  <Tag bordered={false} style={{ margin: 0, background: 'var(--color-surface-2)', color: 'var(--color-text-secondary)', borderRadius: 999 }}>
                    手动触发
                  </Tag>
                )}
                <div style={{ fontSize: 12.5, color: 'var(--color-text-tertiary)', marginTop: 10 }}>
                  上次运行 {r.lastRunAt ? new Date(r.lastRunAt).toLocaleString() : '尚未运行'}
                </div>
              </div>

              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 'auto', paddingTop: 16, borderTop: '1px solid var(--color-border)' }}>
                <Button type="primary" icon={<ThunderboltOutlined />} onClick={() => onEdit(r)} style={{ borderRadius: 12, height: 40, fontWeight: 600 }}>
                  编辑流程
                </Button>
                <Button icon={<PlayCircleOutlined />} onClick={() => { setRunsFor(r); setRunsOpen(true); }} style={{ borderRadius: 12, height: 40 }}>
                  运行 / 历史
                </Button>
                <Popconfirm title="删除？" onConfirm={() => onDelete(r)}>
                  <Button danger style={{ borderRadius: 12, height: 40 }}>
                    删除
                  </Button>
                </Popconfirm>
              </div>
            </div>
          ))}
        </div>
      )}

      {editing && (
        <WorkflowEditor
          open={editorOpen}
          workflow={editing}
          onClose={() => setEditorOpen(false)}
          onSaved={() => {
            setEditorOpen(false);
            load();
          }}
        />
      )}

      {runsFor && (
        <RunsDrawer
          open={runsOpen}
          workflow={runsFor}
          onClose={() => setRunsOpen(false)}
        />
      )}
    </div>
  );
}

// ================== 编辑器 ==================

function WorkflowEditor({
  open, workflow, onClose, onSaved
}: {
  open: boolean;
  workflow: Workflow;
  onClose: () => void;
  onSaved: () => void;
}) {
  const { message } = AntApp.useApp();
  const [form] = Form.useForm();
  const [graphText, setGraphText] = useState(JSON.stringify(workflow.graph, null, 2));
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    form.setFieldsValue({
      name: workflow.name,
      description: workflow.description,
      scheduleCron: workflow.scheduleCron,
      scheduleEnabled: workflow.scheduleEnabled,
      enabled: workflow.enabled
    });
    setGraphText(JSON.stringify(workflow.graph, null, 2));
  }, [workflow]);

  const onSave = async () => {
    const values = await form.validateFields();
    let graph: WorkflowGraph;
    try {
      graph = JSON.parse(graphText);
    } catch (e: any) {
      message.error('Graph JSON 解析失败：' + e.message);
      return;
    }
    if (!graph.entry || !Array.isArray(graph.nodes)) {
      message.error('Graph 必须包含 entry + nodes 数组');
      return;
    }
    setSaving(true);
    try {
      const payload = { ...values, graph };
      if (workflow.id) {
        await WorkflowAPI.update(workflow.id, payload);
      } else {
        await WorkflowAPI.create(payload);
      }
      message.success('已保存');
      onSaved();
    } catch (e: any) {
      message.error('保存失败：' + (e?.message ?? e));
    } finally {
      setSaving(false);
    }
  };

  return (
    <Drawer
      title={workflow.id ? `编辑「${workflow.name}」` : '新建工作流'}
      width={840}
      open={open}
      onClose={onClose}
      styles={{ body: { background: '#fcfcfd' }, header: { background: '#fff', borderBottom: '1px solid var(--color-border)' } }}
      extra={
        <Button type="primary" loading={saving} onClick={onSave} style={{ borderRadius: 10 }}>
          保存
        </Button>
      }
    >
      <Form form={form} layout="vertical">
        <Form.Item label="名称" name="name" rules={[{ required: true, message: '必填' }]}>
          <Input />
        </Form.Item>
        <Form.Item label="描述" name="description">
          <Input.TextArea rows={2} />
        </Form.Item>
        <Space size="large" style={{ marginBottom: 12 }}>
          <Form.Item name="enabled" valuePropName="checked" noStyle>
            <Switch checkedChildren="启用" unCheckedChildren="禁用" />
          </Form.Item>
          <Form.Item name="scheduleEnabled" valuePropName="checked" noStyle>
            <Switch checkedChildren="定时开" unCheckedChildren="定时关" />
          </Form.Item>
        </Space>
        <Form.Item
          label={
            <Space>
              <span>Cron 表达式</span>
              <Text type="secondary" style={{ fontSize: 12 }}>5 段：分 时 日 月 周，例如 "*/30 * * * *"</Text>
            </Space>
          }
          name="scheduleCron"
        >
          <Input placeholder="例如 0 8 * * 1-5（工作日早 8 点）" />
        </Form.Item>
      </Form>

      <NodeQuickAdd
        onAdd={(node) => {
          try {
            const g: WorkflowGraph = JSON.parse(graphText);
            g.nodes = [...(g.nodes || []), node];
            if (!g.entry) g.entry = node.id;
            setGraphText(JSON.stringify(g, null, 2));
          } catch {
            message.error('Graph JSON 不合法，无法追加');
          }
        }}
      />

      <Card
        size="small"
        title={<Text strong>Graph JSON（节点列表）</Text>}
        style={{ marginTop: 12, borderRadius: 16, boxShadow: 'var(--shadow-xs)' }}
        extra={
          <Tooltip title="还原为示例">
            <Button size="small" onClick={() => setGraphText(JSON.stringify(SAMPLE_GRAPH, null, 2))} style={{ borderRadius: 8 }}>
              示例
            </Button>
          </Tooltip>
        }
      >
        <Input.TextArea
          rows={20}
          value={graphText}
          onChange={(e) => setGraphText(e.target.value)}
          style={{ fontFamily: 'ui-monospace, monospace', fontSize: 12 }}
        />
        <Paragraph type="secondary" style={{ fontSize: 12, marginTop: 8 }}>
          支持模板 <code>{'{{input.x}} {{vars.x}} {{steps.<nodeId>.output...}}'}</code>。<br />
          节点类型：agent / skill / http / transform / branch；branch 节点用 <code>condition</code>（返回 bool 的 JS 片段），引擎按 next/elseNext 走。
        </Paragraph>
      </Card>
    </Drawer>
  );
}

function NodeQuickAdd({ onAdd }: { onAdd: (n: WorkflowNode) => void }) {
  const [type, setType] = useState<WorkflowNodeType>('agent');
  const [id, setId] = useState('');
  return (
    <Card size="small" title="快速追加节点" style={{ marginTop: 12, borderRadius: 16, boxShadow: 'var(--shadow-xs)' }}>
      <Space wrap>
        <Select
          value={type}
          style={{ width: 140 }}
          onChange={(v) => setType(v as WorkflowNodeType)}
          options={Object.entries(NODE_TYPE_LABEL).map(([k, label]) => ({
            value: k, label
          }))}
        />
        <Input
          placeholder="节点 id（如 step1）"
          value={id}
          onChange={(e) => setId(e.target.value)}
          style={{ width: 200 }}
        />
        <Button
          type="primary"
          disabled={!id.trim()}
          style={{ borderRadius: 10 }}
          onClick={() => {
            const base: WorkflowNode = {
              id: id.trim(),
              type,
              name: NODE_TYPE_LABEL[type],
              config: defaultConfig(type),
              next: ''
            };
            if (type === 'branch') base.elseNext = '';
            onAdd(base);
            setId('');
          }}
        >
          追加
        </Button>
      </Space>
    </Card>
  );
}

function defaultConfig(type: WorkflowNodeType): Record<string, any> {
  switch (type) {
    case 'agent':
      return { agentId: '', prompt: '请帮我处理：{{input.text}}' };
    case 'skill':
      return { skillId: '', args: {} };
    case 'http':
      return { method: 'GET', url: 'https://example.com/api', headers: {}, body: null };
    case 'transform':
      return { code: 'return { value: input.text };' };
    case 'branch':
      return { condition: 'steps.prev?.output?.value === true' };
  }
}

// ================== 运行抽屉 ==================

function RunsDrawer({
  open, workflow, onClose
}: {
  open: boolean;
  workflow: Workflow;
  onClose: () => void;
}) {
  const { message } = AntApp.useApp();
  const [tab, setTab] = useState('run');
  const [runs, setRuns] = useState<WorkflowRun[]>([]);
  const [detail, setDetail] = useState<WorkflowRunDetail | null>(null);
  const [streaming, setStreaming] = useState(false);
  const [steps, setSteps] = useState<any[]>([]);
  const [finalRun, setFinalRun] = useState<any>(null);
  const [inputJson, setInputJson] = useState('{}');

  const loadRuns = async () => {
    try {
      const data = await WorkflowAPI.listRuns(workflow.id, 30);
      setRuns(data);
    } catch (e: any) {
      message.error('加载历史失败：' + (e?.message ?? e));
    }
  };

  useEffect(() => {
    if (open) loadRuns();
  }, [open]);

  const onRunStream = () => {
    let input: any = undefined;
    if (inputJson.trim()) {
      try {
        input = JSON.parse(inputJson);
      } catch (e: any) {
        message.error('input JSON 不合法');
        return;
      }
    }
    setSteps([]);
    setFinalRun(null);
    setStreaming(true);
    streamWorkflowRun(workflow.id, input, {
      onStepStart: (d) => {
        setSteps((s) => [...s, { ...d, status: 'running' }]);
      },
      onStepFinish: (d) => {
        setSteps((s) => {
          const idx = [...s].reverse().findIndex((x) => x.nodeId === d.nodeId && x.status === 'running');
          if (idx === -1) return [...s, d];
          const realIdx = s.length - 1 - idx;
          const cp = [...s];
          cp[realIdx] = d;
          return cp;
        });
      },
      onRunFinish: (d) => {
        setStreaming(false);
        setFinalRun(d);
        loadRuns();
      },
      onError: (msg) => {
        setStreaming(false);
        message.error(msg);
      }
    });
  };

  const showDetail = async (runId: string) => {
    try {
      const d = await WorkflowAPI.getRun(runId);
      setDetail(d);
    } catch (e: any) {
      message.error('加载详情失败：' + (e?.message ?? e));
    }
  };

  return (
    <Drawer
      title={`运行：${workflow.name}`}
      width={760}
      open={open}
      onClose={() => { setDetail(null); onClose(); }}
      styles={{ body: { background: '#fcfcfd' }, header: { background: '#fff', borderBottom: '1px solid var(--color-border)' } }}
    >
      <Tabs
        activeKey={tab}
        onChange={setTab}
        items={[
          {
            key: 'run',
            label: '触发',
            children: (
              <div>
                <Form layout="vertical">
                  <Form.Item label="Input（JSON，会作为 input.* 注入）">
                    <Input.TextArea
                      rows={4}
                      value={inputJson}
                      onChange={(e) => setInputJson(e.target.value)}
                      placeholder='{"text":"hello"}'
                    />
                  </Form.Item>
                </Form>
                <Space style={{ marginBottom: 12 }}>
                  <Button type="primary" loading={streaming} onClick={onRunStream} style={{ borderRadius: 10 }}>
                    ▶ 流式执行
                  </Button>
                  <Button
                    style={{ borderRadius: 10 }}
                    onClick={async () => {
                      try {
                        const r = await WorkflowAPI.run(workflow.id, JSON.parse(inputJson || '{}'));
                        message.success(`已触发 run=${r.runId}`);
                        loadRuns();
                      } catch (e: any) {
                        message.error('触发失败：' + (e?.message ?? e));
                      }
                    }}
                  >
                    同步执行（不看进度）
                  </Button>
                </Space>

                {steps.length > 0 && (
                  <Card size="small" title="实时进度" style={{ marginBottom: 12, borderRadius: 16 }}>
                    {steps.map((s, i) => (
                      <div key={i} style={{ marginBottom: 8 }}>
                        <Space>
                          <Tag color={STATUS_COLOR[s.status] || 'default'}>{s.status}</Tag>
                          <Text strong>{s.nodeId}</Text>
                          <Text type="secondary">{s.nodeType}</Text>
                          {s.durationMs != null && <Text type="secondary">{s.durationMs}ms</Text>}
                        </Space>
                        {s.error && <Paragraph type="danger" style={{ marginBottom: 0 }}>{s.error}</Paragraph>}
                        {s.output != null && (
                          <pre style={{ background: '#f5f5f5', padding: 6, borderRadius: 4, fontSize: 12, marginTop: 4, maxHeight: 160, overflow: 'auto' }}>
                            {JSON.stringify(s.output, null, 2)}
                          </pre>
                        )}
                      </div>
                    ))}
                  </Card>
                )}

                {finalRun && (
                  <Card size="small" title="最终结果" style={{ borderRadius: 16 }}>
                    <pre style={{ fontSize: 12, margin: 0 }}>
                      {JSON.stringify(finalRun, null, 2)}
                    </pre>
                  </Card>
                )}
              </div>
            )
          },
          {
            key: 'history',
            label: `历史 (${runs.length})`,
            children: (
              <div>
                <Button size="small" onClick={loadRuns} style={{ marginBottom: 8, borderRadius: 8 }}>刷新</Button>
                <Table<WorkflowRun>
                  rowKey="id"
                  size="small"
                  pagination={false}
                  dataSource={runs}
                  columns={[
                    { title: '状态', dataIndex: 'status', render: (s) => <Tag color={STATUS_COLOR[s] || 'default'}>{s}</Tag>, width: 100 },
                    { title: '触发', dataIndex: 'trigger', width: 80 },
                    { title: '开始', dataIndex: 'startedAt', render: (v) => new Date(v).toLocaleString(), width: 180 },
                    { title: '耗时', dataIndex: 'durationMs', render: (v) => `${v} ms`, width: 100 },
                    { title: '', render: (_, r) => <Button size="small" onClick={() => showDetail(r.id)}>详情</Button> }
                  ]}
                />
                {detail && (
                  <Modal
                    title={`Run ${detail.id}`}
                    open
                    onCancel={() => setDetail(null)}
                    onOk={() => setDetail(null)}
                    width={680}
                  >
                    <p><b>状态：</b><Tag color={STATUS_COLOR[detail.status] || 'default'}>{detail.status}</Tag>{detail.error && <Text type="danger" style={{ marginLeft: 8 }}>{detail.error}</Text>}</p>
                    <p><b>耗时：</b>{detail.durationMs} ms</p>
                    <p><b>Input：</b></p>
                    <pre style={{ background: '#f5f5f5', padding: 8, fontSize: 12 }}>{JSON.stringify(detail.input, null, 2)}</pre>
                    <p><b>Steps：</b></p>
                    {detail.steps.map((s) => (
                      <Card size="small" key={s.id} style={{ marginBottom: 8, borderRadius: 14 }}>
                        <Space>
                          <Tag color={STATUS_COLOR[s.status] || 'default'}>{s.status}</Tag>
                          <Text strong>{s.nodeId}</Text>
                          <Text type="secondary">{s.nodeType}</Text>
                          <Text type="secondary">{s.durationMs} ms</Text>
                        </Space>
                        {s.error && <p style={{ color: 'red', marginTop: 4 }}>{s.error}</p>}
                        {s.output != null && (
                          <pre style={{ fontSize: 12, marginTop: 4, maxHeight: 200, overflow: 'auto' }}>
                            {JSON.stringify(s.output, null, 2)}
                          </pre>
                        )}
                      </Card>
                    ))}
                  </Modal>
                )}
              </div>
            )
          }
        ]}
      />
    </Drawer>
  );
}
