import { useState, useCallback, useEffect } from 'react'
import {
  HelpCircle,
  Zap,
  CheckCircle,
  Play,
  Check,
  X,
  Copy,
  Trash2,
  GripVertical,
  AlertCircle,
  AlertTriangle,
  ChevronDown,
  ChevronRight,
  ChevronsDownUp,
  ChevronsUpDown,
} from 'lucide-react'
import { useTreeEditorStore } from '@/store/treeEditorStore'
import { NodeFormDecision } from './NodeFormDecision'
import { NodeFormAction } from './NodeFormAction'
import { NodeFormResolution } from './NodeFormResolution'
import type { TreeStructure } from '@/types'
import { cn } from '@/lib/utils'

interface TreeCanvasNodeProps {
  node: TreeStructure
  depth: number
  fromOption?: string
  isExpanded: boolean
  isNew: boolean
  hasChildren?: boolean
  isSubtreeCollapsed?: boolean
  onToggleExpand: () => void
  onToggleSubtreeCollapse?: () => void
  onSave: (nodeId: string, updates: Partial<TreeStructure>) => void
  onCancelNew: (nodeId: string) => void
  onDelete: (nodeId: string) => void
  onDuplicate: (nodeId: string) => void
  onDragStart: (e: React.DragEvent, nodeId: string) => void
  onDragOver: (e: React.DragEvent) => void
  onDrop: (e: React.DragEvent) => void
}

/** Clone a node without its children (for local draft state) */
function cloneNodeWithoutChildren(node: TreeStructure): TreeStructure {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const { children, ...rest } = node
  return structuredClone(rest) as TreeStructure
}

const NODE_TYPE_CONFIG = {
  decision: {
    icon: HelpCircle,
    label: 'Decision',
    borderClass: 'border-l-4 border-l-blue-500',
    badgeClass: 'bg-blue-500/20 text-blue-400',
  },
  action: {
    icon: Zap,
    label: 'Action',
    borderClass: 'border-l-4 border-l-yellow-500',
    badgeClass: 'bg-yellow-500/20 text-yellow-400',
  },
  solution: {
    icon: CheckCircle,
    label: 'Solution',
    borderClass: 'border-l-4 border-l-green-500',
    badgeClass: 'bg-green-500/20 text-green-400',
  },
} as const

export function TreeCanvasNode({
  node,
  fromOption,
  isExpanded,
  isNew,
  hasChildren = false,
  isSubtreeCollapsed = false,
  onToggleExpand,
  onToggleSubtreeCollapse,
  onSave,
  onCancelNew,
  onDelete,
  onDuplicate,
  onDragStart,
  onDragOver,
  onDrop,
}: TreeCanvasNodeProps) {
  const { validationErrors, selectedNodeId, selectNode } = useTreeEditorStore()
  const isRoot = node.id === 'root'
  const isSelected = selectedNodeId === node.id

  const nodeErrors = validationErrors.filter(
    (e) => e.nodeId === node.id && e.severity === 'error'
  )
  const nodeWarnings = validationErrors.filter(
    (e) => e.nodeId === node.id && e.severity === 'warning'
  )
  const hasError = nodeErrors.length > 0
  const hasWarning = nodeWarnings.length > 0

  // Local draft state for inline editing
  const [draft, setDraft] = useState<TreeStructure>(() =>
    cloneNodeWithoutChildren(node)
  )

  // Reset draft if node ID changes (e.g. navigating between nodes)
  const [lastNodeId, setLastNodeId] = useState(node.id)
  if (node.id !== lastNodeId) {
    setDraft(cloneNodeWithoutChildren(node))
    setLastNodeId(node.id)
  }

  // Re-sync draft from store whenever the card is opened, so stale next_node_id
  // values (written back after stub creation) don't cause duplicate stubs on re-save
  useEffect(() => {
    if (isExpanded) {
      setDraft(cloneNodeWithoutChildren(node))
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isExpanded])

  const handleDraftUpdate = useCallback((updates: Partial<TreeStructure>) => {
    setDraft((prev) => ({ ...prev, ...updates }))
  }, [])

  const handleSave = (e: React.MouseEvent) => {
    e.stopPropagation()
    // Strip children from draft before passing to onSave
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const { children, ...draftWithoutChildren } = draft
    onSave(node.id, draftWithoutChildren)
  }

  const handleCancel = (e: React.MouseEvent) => {
    e.stopPropagation()
    if (isNew) {
      onCancelNew(node.id)
    } else {
      // Discard draft changes and collapse
      setDraft(cloneNodeWithoutChildren(node))
      onToggleExpand()
    }
  }

  const handleCardClick = () => {
    selectNode(node.id)
    onToggleExpand()
  }

  const config = node.type in NODE_TYPE_CONFIG
    ? NODE_TYPE_CONFIG[node.type as keyof typeof NODE_TYPE_CONFIG]
    : NODE_TYPE_CONFIG.decision  // fallback for 'answer' (rendered by AnswerStubCard)
  const TypeIcon = config.icon

  const getTitle = () => {
    if (node.type === 'decision') return node.question || 'Untitled Question'
    return node.title || `Untitled ${node.type}`
  }

  const getOptionsSummary = () => {
    if (node.type !== 'decision' || !node.options?.length) return null
    const count = node.options.length
    return `${count} option${count !== 1 ? 's' : ''}`
  }

  return (
    <div
      className={cn(
        'relative rounded-xl border border-border bg-card shadow-sm transition-all duration-150',
        config.borderClass,
        isExpanded && 'ring-1 ring-primary shadow-md',
        isSelected && !isExpanded && 'ring-1 ring-primary/50',
        hasError && 'ring-1 ring-destructive',
        hasWarning && !hasError && 'ring-1 ring-yellow-500/70',
        isNew && 'ring-1 ring-yellow-400/60',
        'min-w-[240px] max-w-[340px]'
      )}
      onDragOver={onDragOver}
      onDrop={onDrop}
    >
      {/* Card Header */}
      <div
        className={cn(
          'flex items-center gap-2 px-3 py-2.5',
          !isExpanded && 'cursor-pointer hover:bg-accent/50 rounded-t-xl',
          !isExpanded && 'rounded-xl',
          isExpanded && 'sticky top-0 z-10 bg-card rounded-t-xl'
        )}
        onClick={!isExpanded ? handleCardClick : undefined}
      >
        {/* Drag handle (hide for root) */}
        {!isRoot && (
          <span
            className="cursor-grab shrink-0"
            draggable
            onDragStart={(e) => {
              e.stopPropagation()
              onDragStart(e, node.id)
            }}
          >
            <GripVertical className="h-4 w-4 text-muted-foreground/50" />
          </span>
        )}

        {/* Node type badge */}
        {isRoot ? (
          <span className="flex items-center gap-1 rounded px-1.5 py-0.5 text-xs font-semibold bg-blue-500/30 text-blue-400 font-label shrink-0">
            <Play className="h-3 w-3" />
            START
          </span>
        ) : (
          <span
            className={cn(
              'flex items-center gap-1 rounded px-1.5 py-0.5 text-xs font-label shrink-0',
              config.badgeClass
            )}
          >
            <TypeIcon className="h-3 w-3" />
            {config.label}
          </span>
        )}

        {/* From-option label */}
        {fromOption && (
          <span className="rounded bg-muted px-1.5 py-0.5 text-[10px] text-muted-foreground truncate max-w-[80px]">
            {fromOption}
          </span>
        )}

        {/* Title text (compact mode) */}
        {!isExpanded && (
          <span className="flex-1 truncate text-sm font-heading font-medium text-foreground">
            {getTitle()}
          </span>
        )}

        {/* Options count badge */}
        {!isExpanded && getOptionsSummary() && (
          <span className="text-[10px] text-muted-foreground shrink-0 font-label">
            {getOptionsSummary()}
          </span>
        )}

        {/* Validation badges (compact mode) */}
        {!isExpanded && hasError && (
          <span
            className="flex items-center gap-0.5 rounded bg-destructive/20 px-1.5 py-0.5 text-[10px] text-destructive shrink-0"
            title={nodeErrors.map((e) => e.message).join('\n')}
          >
            <AlertCircle className="h-2.5 w-2.5" />
            {nodeErrors.length}
          </span>
        )}
        {!isExpanded && !hasError && hasWarning && (
          <span
            className="flex items-center gap-0.5 rounded bg-yellow-500/20 px-1.5 py-0.5 text-[10px] text-yellow-500 shrink-0"
            title={nodeWarnings.map((e) => e.message).join('\n')}
          >
            <AlertTriangle className="h-2.5 w-2.5" />
            {nodeWarnings.length}
          </span>
        )}

        {/* Unsaved badge */}
        {!isExpanded && isNew && (
          <span className="rounded bg-yellow-500/20 px-1.5 py-0.5 text-[10px] text-yellow-500 font-label shrink-0">
            Unsaved
          </span>
        )}

        {/* Subtree collapse toggle — only in compact mode when node has children */}
        {!isExpanded && hasChildren && onToggleSubtreeCollapse && (
          <button
            type="button"
            onClick={(e) => { e.stopPropagation(); onToggleSubtreeCollapse() }}
            title={isSubtreeCollapsed ? 'Expand subtree' : 'Collapse subtree'}
            className="rounded p-0.5 text-muted-foreground/50 hover:bg-accent hover:text-foreground shrink-0"
          >
            {isSubtreeCollapsed
              ? <ChevronsUpDown className="h-3.5 w-3.5" />
              : <ChevronsDownUp className="h-3.5 w-3.5" />
            }
          </button>
        )}

        {/* Expand/collapse chevron */}
        {!isExpanded ? (
          <ChevronRight className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
        ) : (
          <ChevronDown className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
        )}

        {/* Editing action buttons (expanded state) */}
        {isExpanded && (
          <div className="ml-auto flex items-center gap-1 shrink-0">
            {/* New badge */}
            {isNew && (
              <span className="rounded bg-yellow-500/20 px-1.5 py-0.5 text-[10px] text-yellow-500 font-label">
                Unsaved
              </span>
            )}

            {/* Duplicate (hide for root) */}
            {!isRoot && (
              <button
                type="button"
                onClick={(e) => {
                  e.stopPropagation()
                  onDuplicate(node.id)
                }}
                title="Duplicate node"
                className="rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
              >
                <Copy className="h-3.5 w-3.5" />
              </button>
            )}

            {/* Delete (hide for root) */}
            {!isRoot && (
              <button
                type="button"
                onClick={(e) => {
                  e.stopPropagation()
                  onDelete(node.id)
                }}
                title="Delete node"
                className="rounded p-1 text-muted-foreground hover:bg-destructive/20 hover:text-destructive"
              >
                <Trash2 className="h-3.5 w-3.5" />
              </button>
            )}

            {/* Cancel */}
            <button
              type="button"
              onClick={handleCancel}
              title={isNew ? 'Cancel (deletes this node)' : 'Cancel changes'}
              className="rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground"
            >
              <X className="h-3.5 w-3.5" />
            </button>

            {/* Save */}
            <button
              type="button"
              onClick={handleSave}
              title="Save changes"
              className="rounded p-1 bg-gradient-brand text-white hover:opacity-90"
            >
              <Check className="h-3.5 w-3.5" />
            </button>
          </div>
        )}
      </div>

      {/* Expanded editing area */}
      {isExpanded && (
        <div className="border-t border-border px-3 pb-3 pt-3 max-h-[70vh] overflow-y-auto">
          {/* Validation errors */}
          {(hasError || hasWarning) && (
            <div className="mb-3 space-y-1">
              {nodeErrors.map((error, i) => (
                <div
                  key={i}
                  className="rounded-md bg-red-400/10 px-3 py-2 text-xs text-red-400"
                >
                  {error.message}
                </div>
              ))}
              {!hasError &&
                nodeWarnings.map((warning, i) => (
                  <div
                    key={i}
                    className="rounded-md bg-yellow-400/10 px-3 py-2 text-xs text-yellow-400"
                  >
                    {warning.message}
                  </div>
                ))}
            </div>
          )}

          {/* Type-specific form — uses draft, not live node */}
          {draft.type === 'decision' && (
            <NodeFormDecision node={draft} onUpdate={handleDraftUpdate} />
          )}
          {draft.type === 'action' && (
            <NodeFormAction node={draft} onUpdate={handleDraftUpdate} />
          )}
          {draft.type === 'solution' && (
            <NodeFormResolution node={draft} onUpdate={handleDraftUpdate} />
          )}
        </div>
      )}
    </div>
  )
}

export default TreeCanvasNode
