import { useMemo } from 'react'
import { useTreeEditorStore } from '@/store/treeEditorStore'
import type { NodeType } from '@/types'
import { cn } from '@/lib/utils'

// Special values for creating new nodes
const CREATE_PREFIX = '__create_'
const CREATE_DECISION = `${CREATE_PREFIX}decision__`
const CREATE_ACTION = `${CREATE_PREFIX}action__`
const CREATE_SOLUTION = `${CREATE_PREFIX}solution__`

// Unicode symbols for node types (works in select options)
const NODE_TYPE_SYMBOLS: Record<NodeType, string> = {
  decision: 'ⓘ',  // Information/question symbol
  action: '⚡',    // Lightning bolt for action
  solution: '✓'   // Checkmark for solution
}

interface NodePickerProps {
  value: string
  onChange: (nodeId: string) => void
  /** The parent node ID - new nodes will be added as children of this node */
  parentNodeId: string
  excludeNodeId?: string
  placeholder?: string
  className?: string
  label?: string
  error?: string
  /** Callback when a new node is created (receives the new node ID) */
  onNodeCreated?: (nodeId: string) => void
}

export function NodePicker({
  value,
  onChange,
  parentNodeId,
  excludeNodeId,
  placeholder = 'Select a node...',
  className,
  label,
  error,
  onNodeCreated
}: NodePickerProps) {
  const { getAvailableTargetNodes, addNode } = useTreeEditorStore()
  const availableNodes = getAvailableTargetNodes(excludeNodeId)

  // Group nodes by type
  const groupedNodes = useMemo(() => {
    const decisions = availableNodes.filter(n => n.type === 'decision')
    const actions = availableNodes.filter(n => n.type === 'action')
    const solutions = availableNodes.filter(n => n.type === 'solution')
    return { decisions, actions, solutions }
  }, [availableNodes])

  const handleChange = (selectedValue: string) => {
    // Check if it's a "create new" option
    if (selectedValue.startsWith(CREATE_PREFIX)) {
      let nodeType: NodeType
      if (selectedValue === CREATE_DECISION) {
        nodeType = 'decision'
      } else if (selectedValue === CREATE_ACTION) {
        nodeType = 'action'
      } else if (selectedValue === CREATE_SOLUTION) {
        nodeType = 'solution'
      } else {
        return
      }

      // Create the new node as a child of the parent
      const newNodeId = addNode(parentNodeId, nodeType)

      // Set this new node as the selected value
      onChange(newNodeId)

      // Notify parent if callback provided
      onNodeCreated?.(newNodeId)
    } else {
      // Normal selection
      onChange(selectedValue)
    }
  }

  // Find the label for the currently selected node
  const selectedNode = availableNodes.find(n => n.id === value)

  return (
    <div className={className}>
      {label && (
        <label className="mb-1 block text-sm font-medium text-foreground">
          {label}
        </label>
      )}
      <select
        value={value || ''}
        onChange={(e) => handleChange(e.target.value)}
        className={cn(
          'block w-full rounded-md border px-3 py-2 text-sm',
          'bg-background text-foreground',
          'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary',
          error ? 'border-destructive' : 'border-input'
        )}
      >
        <option value="">{placeholder}</option>

        {/* Create new options */}
        <optgroup label="Create New Node">
          <option value={CREATE_DECISION}>+ New Decision (question)</option>
          <option value={CREATE_ACTION}>+ New Action (task)</option>
          <option value={CREATE_SOLUTION}>+ New Solution (endpoint)</option>
        </optgroup>

        {/* Existing nodes grouped by type */}
        {groupedNodes.decisions.length > 0 && (
          <optgroup label="── Decisions ──">
            {groupedNodes.decisions.map((node) => (
              <option key={node.id} value={node.id}>
                {NODE_TYPE_SYMBOLS.decision} {node.label}
              </option>
            ))}
          </optgroup>
        )}

        {groupedNodes.actions.length > 0 && (
          <optgroup label="── Actions ──">
            {groupedNodes.actions.map((node) => (
              <option key={node.id} value={node.id}>
                {NODE_TYPE_SYMBOLS.action} {node.label}
              </option>
            ))}
          </optgroup>
        )}

        {groupedNodes.solutions.length > 0 && (
          <optgroup label="── Solutions ──">
            {groupedNodes.solutions.map((node) => (
              <option key={node.id} value={node.id}>
                {NODE_TYPE_SYMBOLS.solution} {node.label}
              </option>
            ))}
          </optgroup>
        )}
      </select>

      {/* Show what's selected */}
      {value && selectedNode && (
        <p className="mt-1 text-xs text-muted-foreground">
          → {selectedNode.label}
        </p>
      )}

      {error && <p className="mt-1 text-xs text-destructive">{error}</p>}
    </div>
  )
}

export default NodePicker
