import { useEffect, useCallback, useState, useRef, lazy, Suspense } from 'react';
import { Button, message, Modal, Spin, Table, Tag } from 'antd';
import { EyeOutlined, PauseCircleOutlined, PlayCircleOutlined, StopOutlined } from '@ant-design/icons';
import type { ColumnsType } from 'antd/es/table';
import {
  listInstances,
  resumeInstance,
  suspendInstance,
  terminateInstance,
  type ProcessInstanceInfo,
} from '../../api/workflowInstances';
import { getProcessDefinition, type NodeDef, type EdgeDef } from '../../api/workflowDefinitions';

const ProcessViewer = lazy(() => import('./ProcessViewer'));
import { useThemeMode } from '../../hooks/useThemeMode';

const statusStyles: Record<string, { bg: string; color: string; text: string }> = {
  running: { bg: '#eff6ff', color: '#2563eb', text: '运行中' },
  suspended: { bg: '#FFFBEB', color: '#d97706', text: '已挂起' },
  completed: { bg: '#ECFDF5', color: '#059669', text: '已完成' },
  terminated: { bg: '#FEF2F2', color: '#dc2626', text: '已终止' },
};

export default function InstanceMonitor() {
  const [data, setData] = useState<ProcessInstanceInfo[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [loading, setLoading] = useState(false);

  const [viewerOpen, setViewerOpen] = useState(false);
  const [viewerNodes, setViewerNodes] = useState<NodeDef[]>([]);
  const [viewerEdges, setViewerEdges] = useState<EdgeDef[]>([]);
  const [activeNodeIds, setActiveNodeIds] = useState<string[]>([]);
  const [viewerLoading, setViewerLoading] = useState(false);
  const isDark = useThemeMode();

  // 流程定义缓存：definition_id -> nodes 映射
  const definitionCache = useRef<Record<string, NodeDef[]>>({});

  const resolveNodeNames = useCallback((defId: string, nodeIds: string[]): string => {
    const nodes = definitionCache.current[defId];
    if (!nodes) return nodeIds.join(', ');
    return nodeIds
      .map((nid) => {
        const node = nodes.find((n) => n.id === nid);
        return node ? node.name : nid;
      })
      .join(', ');
  }, []);

  // 加载当前页实例对应的流程定义
  const loadDefinitions = useCallback(async (instances: ProcessInstanceInfo[]) => {
    const uncached = new Set<string>();
    for (const inst of instances) {
      if (!definitionCache.current[inst.definition_id]) {
        uncached.add(inst.definition_id);
      }
    }
    await Promise.all(
      Array.from(uncached).map(async (defId) => {
        try {
          const def = await getProcessDefinition(defId);
          definitionCache.current[defId] = def.nodes;
        } catch {
          // 静默，将显示原始 node_id
        }
      }),
    );
  }, []);

  // 触发重渲染当定义缓存更新后
  const [, forceUpdate] = useState(0);
  useEffect(() => {
    if (data.length > 0) {
      loadDefinitions(data).then(() => forceUpdate((n) => n + 1));
    }
  // 仅在 data 变化时触发，避免无限循环
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [data]);

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const res = await listInstances(page, 20);
      setData(res.data);
      setTotal(res.total);
    } finally {
      setLoading(false);
    }
  }, [page]);

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

  const handleViewFlow = async (record: ProcessInstanceInfo) => {
    setViewerLoading(true);
    setViewerOpen(true);
    try {
      const def = await getProcessDefinition(record.definition_id);
      setViewerNodes(def.nodes);
      setViewerEdges(def.edges);
      setActiveNodeIds(record.active_tokens.map((t) => t.node_id));
    } catch {
      message.error('加载流程图失败');
      setViewerOpen(false);
    } finally {
      setViewerLoading(false);
    }
  };

  const handleTerminate = async (id: string) => {
    Modal.confirm({
      title: '确认终止',
      content: '确定要终止该流程实例吗？此操作不可撤销。',
      okText: '确定终止',
      okType: 'danger',
      cancelText: '取消',
      onOk: async () => {
        try {
          await terminateInstance(id);
          message.success('已终止');
          fetchData();
        } catch {
          message.error('操作失败');
        }
      },
    });
  };

  const handleSuspend = async (id: string) => {
    Modal.confirm({
      title: '确认挂起',
      content: '确定要挂起该流程实例吗？挂起后可通过"恢复"按钮继续执行。',
      okText: '确定挂起',
      okType: 'default',
      cancelText: '取消',
      onOk: async () => {
        try {
          await suspendInstance(id);
          message.success('已挂起');
          fetchData();
        } catch {
          message.error('操作失败');
        }
      },
    });
  };

  const handleResume = async (id: string) => {
    try {
      await resumeInstance(id);
      message.success('已恢复');
      fetchData();
    } catch {
      message.error('操作失败');
    }
  };

  const columns: ColumnsType<ProcessInstanceInfo> = [
    {
      title: '流程',
      dataIndex: 'definition_name',
      key: 'definition_name',
      render: (v: string) => <span style={{ fontWeight: 500 }}>{v}</span>,
    },
    {
      title: '业务键',
      dataIndex: 'business_key',
      key: 'business_key',
      render: (v: string | undefined) => v || '-',
    },
    {
      title: '状态',
      dataIndex: 'status',
      key: 'status',
      width: 100,
      render: (s: string) => {
        const info = statusStyles[s] || { bg: '#f8fafc', color: '#475569', text: s };
        return (
          <Tag style={{
            background: info.bg,
            border: 'none',
            color: info.color,
            fontWeight: 500,
          }}>
            {info.text}
          </Tag>
        );
      },
    },
    {
      title: '当前节点',
      key: 'current_nodes',
      width: 150,
      render: (_, record) => {
        const nodeIds = record.active_tokens.map((t) => t.node_id);
        if (nodeIds.length === 0) return '-';
        const resolved = resolveNodeNames(record.definition_id, nodeIds);
        return <span>{resolved}</span>;
      },
    },
    {
      title: '发起时间',
      dataIndex: 'started_at',
      key: 'started_at',
      width: 180,
      render: (v: string) => (
        <span style={{ color: isDark ? '#475569' : '#94a3b8', fontSize: 13 }}>
          {new Date(v).toLocaleString()}
        </span>
      ),
    },
    {
      title: '操作',
      key: 'action',
      width: 240,
      render: (_, record) => (
        <div style={{ display: 'flex', gap: 4 }}>
          <Button
            size="small"
            type="text"
            icon={<EyeOutlined />}
            onClick={() => handleViewFlow(record)}
          >
            流程图
          </Button>
          {record.status === 'running' && (
            <>
              <Button
                size="small"
                type="text"
                icon={<PauseCircleOutlined />}
                onClick={() => handleSuspend(record.id)}
              >
                挂起
              </Button>
              <Button
                size="small"
                type="text"
                danger
                icon={<StopOutlined />}
                onClick={() => handleTerminate(record.id)}
              >
                终止
              </Button>
            </>
          )}
          {record.status === 'suspended' && (
            <Button
              size="small"
              type="primary"
              icon={<PlayCircleOutlined />}
              onClick={() => handleResume(record.id)}
            >
              恢复
            </Button>
          )}
        </div>
      ),
    },
  ];

  return (
    <>
      <div style={{
        background: isDark ? '#111827' : '#FFFFFF',
        borderRadius: 12,
        border: `1px solid ${isDark ? '#0f172a' : '#f8fafc'}`,
        overflow: 'hidden',
      }}>
        <Table
          rowKey="id"
          columns={columns}
          dataSource={data}
          loading={loading}
          pagination={{
            current: page,
            total,
            pageSize: 20,
            onChange: setPage,
            showTotal: (t) => `共 ${t} 条记录`,
          }}
        />
      </div>

      <Modal
        title="流程图查看"
        open={viewerOpen}
        onCancel={() => setViewerOpen(false)}
        footer={null}
        width={720}
        loading={viewerLoading}
      >
        <Suspense fallback={<div style={{ textAlign: 'center', padding: 40 }}><Spin /></div>}>
          <ProcessViewer nodes={viewerNodes} edges={viewerEdges} activeNodeIds={activeNodeIds} />
        </Suspense>
      </Modal>
    </>
  );
}
