import { useCallback, useEffect, useMemo, useState } from 'react';
import { Button, Form, Input, message, Spin } from 'antd';
import {
  ReactFlow,
  Controls,
  Background,
  addEdge,
  useNodesState,
  useEdgesState,
  type Connection,
  type Node,
  type Edge,
  BackgroundVariant,
  MarkerType,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import {
  type CreateProcessDefinitionRequest,
  type NodeDef,
  type EdgeDef,
  getProcessDefinition,
} from '../../api/workflowDefinitions';

const NODE_TYPES_MAP: Record<string, { label: string; color: string }> = {
  StartEvent: { label: '开始', color: '#52c41a' },
  EndEvent: { label: '结束', color: '#ff4d4f' },
  UserTask: { label: '用户任务', color: '#1890ff' },
  ServiceTask: { label: '服务任务', color: '#722ed1' },
  ExclusiveGateway: { label: '排他网关', color: '#fa8c16' },
  ParallelGateway: { label: '并行网关', color: '#13c2c2' },
};

const PALETTE_ITEMS = Object.entries(NODE_TYPES_MAP).map(([type, info]) => ({
  type,
  label: info.label,
  color: info.color,
}));

function createFlowNode(type: string, label: string, position: { x: number; y: number }, id?: string): Node {
  return {
    id: id || `node_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`,
    type: 'default',
    position,
    data: { label: `${label}`, nodeType: type, name: label },
    style: {
      background: NODE_TYPES_MAP[type]?.color || '#f0f0f0',
      color: '#fff',
      padding: '8px 16px',
      borderRadius: type.includes('Gateway') ? 0 : type === 'StartEvent' || type === 'EndEvent' ? 50 : 6,
      fontSize: 13,
      fontWeight: 500,
      border: '2px solid rgba(255,255,255,0.3)',
      width: type.includes('Gateway') ? 80 : 140,
      textAlign: 'center' as const,
    },
  };
}

interface ProcessDesignerProps {
  definitionId: string | null;
  onSave: (req: CreateProcessDefinitionRequest, id?: string) => void;
}

export default function ProcessDesigner({ definitionId, onSave }: ProcessDesignerProps) {
  const [form] = Form.useForm();
  const [selectedNode, setSelectedNode] = useState<Node | null>(null);
  const [loading, setLoading] = useState(false);
  const [nodes, setNodes, onNodesChange] = useNodesState<Node>([]);
  const [edges, setEdges, onEdgesChange] = useEdgesState<Edge>([]);

  const isEditing = definitionId !== null;

  // 加载流程定义（编辑模式）或初始化默认节点（新建模式）
  useEffect(() => {
    if (!definitionId) {
      const startNode = createFlowNode('StartEvent', '开始', { x: 250, y: 50 });
      const userNode = createFlowNode('UserTask', '审批', { x: 250, y: 200 });
      const endNode = createFlowNode('EndEvent', '结束', { x: 250, y: 400 });
      setNodes([startNode, userNode, endNode]);
      setEdges([
        { id: 'e_start_approve', source: startNode.id, target: userNode.id, markerEnd: { type: MarkerType.ArrowClosed } },
        { id: 'e_approve_end', source: userNode.id, target: endNode.id, markerEnd: { type: MarkerType.ArrowClosed } },
      ]);
      return;
    }

    setLoading(true);
    getProcessDefinition(definitionId)
      .then((def) => {
        form.setFieldsValue({
          name: def.name,
          key: def.key,
          category: def.category,
          description: def.description,
        });
        const flowNodes = def.nodes.map((n, i) =>
          createFlowNode(n.type, n.name, n.position || { x: 200, y: i * 120 + 50 }, n.id)
        );
        const flowEdges: Edge[] = def.edges.map((e) => ({
          id: e.id,
          source: e.source,
          target: e.target,
          markerEnd: { type: MarkerType.ArrowClosed },
          label: e.label || e.condition,
        }));
        setNodes(flowNodes);
        setEdges(flowEdges);
      })
      .catch(() => message.error('加载流程定义失败'))
      .finally(() => setLoading(false));
  }, [definitionId]); // eslint-disable-line react-hooks/exhaustive-deps

  const onConnect = useCallback(
    (connection: Connection) => {
      setEdges((eds) =>
        addEdge(
          { ...connection, markerEnd: { type: MarkerType.ArrowClosed } },
          eds,
        ),
      );
    },
    [setEdges],
  );

  const onNodeClick = useCallback((_: React.MouseEvent, node: Node) => {
    setSelectedNode(node);
  }, []);

  const handleAddNode = (type: string) => {
    const info = NODE_TYPES_MAP[type];
    if (!info) return;
    const newNode = createFlowNode(type, info.label, {
      x: 100 + Math.random() * 400,
      y: 100 + Math.random() * 300,
    });
    setNodes((nds) => [...nds, newNode]);
  };

  const handleDeleteNode = () => {
    if (!selectedNode) return;
    setNodes((nds) => nds.filter((n) => n.id !== selectedNode.id));
    setEdges((eds) =>
      eds.filter((e) => e.source !== selectedNode.id && e.target !== selectedNode.id),
    );
    setSelectedNode(null);
  };

  const handleUpdateNodeName = (name: string) => {
    if (!selectedNode) return;
    setNodes((nds) =>
      nds.map((n) =>
        n.id === selectedNode.id
          ? { ...n, data: { ...n.data, label: name, name } }
          : n,
      ),
    );
    setSelectedNode((prev) => (prev ? { ...prev, data: { ...prev.data, label: name, name } } : null));
  };

  const handleSave = () => {
    form.validateFields().then((values) => {
      const flowNodes: NodeDef[] = nodes.map((n) => ({
        id: n.id,
        type: (n.data.nodeType as NodeDef['type']) || 'UserTask',
        name: String(n.data.name || n.data.label || ''),
        position: { x: Math.round(n.position.x), y: Math.round(n.position.y) },
      }));
      const flowEdges: EdgeDef[] = edges.map((e) => ({
        id: e.id,
        source: e.source,
        target: e.target,
        label: e.label ? String(e.label) : undefined,
      }));
      onSave(
        { ...values, nodes: flowNodes, edges: flowEdges },
        definitionId || undefined,
      );
    }).catch(() => {
      message.error('请填写必要字段');
    });
  };

  const defaultEdgeOptions = useMemo(
    () => ({
      markerEnd: { type: MarkerType.ArrowClosed },
    }),
    [],
  );

  if (loading) {
    return <div style={{ display: 'flex', justifyContent: 'center', padding: 100 }}><Spin /></div>;
  }

  return (
    <div style={{ display: 'flex', gap: 16, height: 500 }}>
      {/* 左侧工具面板 */}
      <div style={{ width: 180, display: 'flex', flexDirection: 'column', gap: 8 }}>
        <p style={{ fontWeight: 500, margin: '0 0 4px' }}>添加节点</p>
        {PALETTE_ITEMS.map((item) => (
          <Button
            key={item.type}
            size="small"
            style={{ textAlign: 'left' }}
            onClick={() => handleAddNode(item.type)}
          >
            <span style={{
              display: 'inline-block',
              width: 10,
              height: 10,
              borderRadius: 2,
              background: item.color,
              marginRight: 6,
            }} />
            {item.label}
          </Button>
        ))}

        {selectedNode && (
          <div style={{ marginTop: 16, padding: 8, background: '#f5f5f5', borderRadius: 6 }}>
            <p style={{ fontWeight: 500, margin: '0 0 8px', fontSize: 12 }}>节点属性</p>
            <Input
              size="small"
              value={String(selectedNode.data.name || '')}
              onChange={(e) => handleUpdateNodeName(e.target.value)}
              placeholder="节点名称"
              style={{ marginBottom: 8 }}
            />
            <Button size="small" danger onClick={handleDeleteNode} block>
              删除节点
            </Button>
          </div>
        )}
      </div>

      {/* 中间画布 */}
      <div style={{ flex: 1, border: '1px solid #d9d9d9', borderRadius: 6 }}>
        <ReactFlow
          nodes={nodes}
          edges={edges}
          onNodesChange={onNodesChange}
          onEdgesChange={onEdgesChange}
          onConnect={onConnect}
          onNodeClick={onNodeClick}
          defaultEdgeOptions={defaultEdgeOptions}
          fitView
        >
          <Controls />
          <Background variant={BackgroundVariant.Dots} gap={16} size={1} />
        </ReactFlow>
      </div>

      {/* 右侧表单 */}
      <div style={{ width: 220, overflow: 'auto' }}>
        <Form form={form} layout="vertical" size="small">
          <Form.Item name="name" label="流程名称" rules={[{ required: true, message: '请输入' }]}>
            <Input placeholder="请假审批" />
          </Form.Item>
          <Form.Item name="key" label="流程编码" rules={[{ required: true, message: '请输入' }]}>
            <Input placeholder="leave_approval" disabled={isEditing} />
          </Form.Item>
          <Form.Item name="category" label="分类">
            <Input placeholder="leave" />
          </Form.Item>
          <Form.Item name="description" label="描述">
            <Input.TextArea rows={2} />
          </Form.Item>
          <Button type="primary" onClick={handleSave}>{isEditing ? '更新' : '保存'}</Button>
        </Form>
      </div>
    </div>
  );
}
