import { useCallback, useEffect, useRef, useState } from 'react';
import { Background, Controls, Panel, ReactFlow, addEdge, useEdgesState, useNodesState } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import { MarkerType } from '@xyflow/react';
import WorkflowEdge from './WorkflowEdge';
import WorkflowMinimap from './WorkflowMinimap';
import WorkflowNode from './WorkflowNode';
import WorkflowToolbar from './WorkflowToolbar';

const nodeTypes = { workflowNode: WorkflowNode };
const edgeTypes = { workflowEdge: WorkflowEdge, default: WorkflowEdge };

export const NODE_TEMPLATES = [
  { type: 'start', label: 'Start / Trigger', iconName: 'Play', color: '#10B981', category: 'Flow' },
  { type: 'process', label: 'Process', iconName: 'Cpu', color: '#3B82F6', category: 'Flow' },
  { type: 'decision', label: 'Decision', iconName: 'GitBranch', color: '#F59E0B', category: 'Flow' },
  { type: 'database', label: 'Database', iconName: 'Database', color: '#10B981', category: 'Infrastructure' },
  { type: 'api', label: 'API Call', iconName: 'Globe', color: '#06B6D4', category: 'Integration' },
  { type: 'auth', label: 'Auth Check', iconName: 'Lock', color: '#EF4444', category: 'Security' },
  { type: 'notification', label: 'Notification', iconName: 'Bell', color: '#8B5CF6', category: 'Output' },
  { type: 'code', label: 'Code Module', iconName: 'Code', color: '#84CC16', category: 'Code' },
  { type: 'service', label: 'Microservice', iconName: 'Box', color: '#EC4899', category: 'Infrastructure' },
  { type: 'queue', label: 'Message Queue', iconName: 'Layers', color: '#F97316', category: 'Infrastructure' },
  { type: 'cloud', label: 'Cloud Service', iconName: 'Cloud', color: '#14B8A6', category: 'Infrastructure' },
];

let nodeIdCounter = 1;

export default function WorkflowDesigner({ initialNodes = [], initialEdges = [] }) {
  const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
  const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
  const [isDraggingOver, setIsDraggingOver] = useState(false);
  const [reactFlowInstance, setReactFlowInstance] = useState(null);
  const wrapperRef = useRef(null);

  useEffect(() => {
    setNodes(initialNodes);
    setEdges(initialEdges);
  }, [initialEdges, initialNodes, setEdges, setNodes]);

  const onConnect = useCallback(
    (params) =>
      setEdges((current) =>
        addEdge(
          {
            ...params,
            type: 'workflowEdge',
            markerEnd: { type: MarkerType.ArrowClosed, color: '#38BDF8' },
            animated: true,
          },
          current,
        ),
      ),
    [setEdges],
  );

  const onDragStart = (event, template) => {
    event.dataTransfer.setData('application/workflow-node', JSON.stringify(template));
    event.dataTransfer.effectAllowed = 'move';
  };

  const onDragOver = useCallback((event) => {
    event.preventDefault();
    event.dataTransfer.dropEffect = 'move';
    setIsDraggingOver(true);
  }, []);

  const onDrop = useCallback(
    (event) => {
      event.preventDefault();
      setIsDraggingOver(false);
      const raw = event.dataTransfer.getData('application/workflow-node');
      if (!raw || !reactFlowInstance) return;
      const template = JSON.parse(raw);
      const position = reactFlowInstance.screenToFlowPosition({
        x: event.clientX,
        y: event.clientY,
      });
      setNodes((current) =>
        current.concat({
          id: `node_${nodeIdCounter++}`,
          type: 'workflowNode',
          position,
          data: { ...template, nodeType: template.type, description: '' },
        }),
      );
    },
    [reactFlowInstance, setNodes],
  );

  const addNode = (template = NODE_TEMPLATES[0]) => {
    setNodes((current) =>
      current.concat({
        id: `node_${nodeIdCounter++}`,
        type: 'workflowNode',
        position: { x: 120 + current.length * 35, y: 120 + current.length * 24 },
        data: { ...template, nodeType: template.type, description: '' },
      }),
    );
  };

  const deleteSelected = () => {
    setNodes((current) => current.filter((node) => !node.selected));
    setEdges((current) => current.filter((edge) => !edge.selected));
  };

  const exportWorkflow = () => {
    const blob = new Blob([JSON.stringify({ nodes, edges, timestamp: new Date().toISOString() }, null, 2)], {
      type: 'application/json',
    });
    const url = URL.createObjectURL(blob);
    const anchor = document.createElement('a');
    anchor.href = url;
    anchor.download = 'codeatlas-workflow.json';
    anchor.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div className="flex h-full min-h-[720px] overflow-hidden rounded-lg border border-white/10">
      <WorkflowToolbar templates={NODE_TEMPLATES} onDragStart={onDragStart} />
      <div className="relative flex-1" ref={wrapperRef}>
        <ReactFlow
          nodes={nodes}
          edges={edges}
          onNodesChange={onNodesChange}
          onEdgesChange={onEdgesChange}
          onConnect={onConnect}
          onInit={setReactFlowInstance}
          onDrop={onDrop}
          onDragOver={onDragOver}
          onDragLeave={() => setIsDraggingOver(false)}
          nodeTypes={nodeTypes}
          edgeTypes={edgeTypes}
          fitView
          deleteKeyCode="Delete"
          style={{ background: isDraggingOver ? 'rgba(56,189,248,0.05)' : '#080b14' }}
        >
          <Background color="#263144" gap={28} size={1} />
          <Controls />
          <WorkflowMinimap />
          <Panel position="top-right">
            <div className="flex gap-2">
              <button onClick={() => addNode()} className="rounded-lg border border-cyan-400/25 bg-cyan-500/12 px-3 py-2 text-xs font-medium text-cyan-200">
                Add Node
              </button>
              <button onClick={deleteSelected} className="rounded-lg border border-red-400/25 bg-red-500/12 px-3 py-2 text-xs font-medium text-red-200">
                Delete
              </button>
              <button onClick={exportWorkflow} className="rounded-lg border border-white/10 bg-white/5 px-3 py-2 text-xs font-medium text-slate-200">
                Export
              </button>
            </div>
          </Panel>
        </ReactFlow>
      </div>
    </div>
  );
}
