import { useEffect, useState } from 'react'
import { useParams, useNavigate, useLocation } from 'react-router-dom'
import { treesApi, sessionsApi, stepsApi } from '@/api'
import { useTreeNavigationShortcuts } from '@/hooks/useKeyboardShortcuts'
import type { Tree, Session, DecisionRecord, TreeStructure, CustomStep, Step } from '@/types'
import type { CustomStepDraft } from '@/components/step-library/CustomStepModal'
import { cn } from '@/lib/utils'
import { MarkdownContent } from '@/components/ui/MarkdownContent'
import { CustomStepModal } from '@/components/step-library/CustomStepModal'
import { PostStepActionModal, ContinuationModal, ForkTreeModal, ScratchpadSidebar, type DescendantNode } from '@/components/session'
import { Plus, CheckCircle, ArrowRight } from 'lucide-react'

interface LocationState {
  sessionId?: string
}

export function TreeNavigationPage() {
  const { id: treeId } = useParams<{ id: string }>()
  const navigate = useNavigate()
  const location = useLocation()
  const locationState = location.state as LocationState | undefined

  const [tree, setTree] = useState<Tree | null>(null)
  const [session, setSession] = useState<Session | null>(null)
  const [currentNodeId, setCurrentNodeId] = useState<string>('root')
  const [pathTaken, setPathTaken] = useState<string[]>(['root'])
  const [decisions, setDecisions] = useState<DecisionRecord[]>([])
  const [notes, setNotes] = useState<string>('')
  const [isLoading, setIsLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [isCompleting, setIsCompleting] = useState(false)

  // Session metadata
  const [ticketNumber, setTicketNumber] = useState<string>('')
  const [clientName, setClientName] = useState<string>('')
  const [showMetadataForm, setShowMetadataForm] = useState(true)

  // Custom steps
  const [customSteps, setCustomSteps] = useState<CustomStep[]>([])
  const [showCustomStepModal, setShowCustomStepModal] = useState(false)

  // Post-step action flow
  const [showPostStepModal, setShowPostStepModal] = useState(false)
  const [pendingStep, setPendingStep] = useState<Step | CustomStepDraft | null>(null)
  const [pendingStepIsFromLibrary, setPendingStepIsFromLibrary] = useState(false)
  const [isSavingStep, setIsSavingStep] = useState(false)

  // Continuation flow
  const [showContinuationModal, setShowContinuationModal] = useState(false)
  const [branchOriginNodeId, setBranchOriginNodeId] = useState<string | null>(null)
  const [pendingContinuationNodeId, setPendingContinuationNodeId] = useState<string | null>(null)

  // Custom branch mode
  const [customBranchMode, setCustomBranchMode] = useState(false)

  // Fork flow
  const [showForkModal, setShowForkModal] = useState(false)

  // Scratchpad save handler
  const handleScratchpadSave = async (content: string) => {
    if (!session) return
    await sessionsApi.updateScratchpad(session.id, content)
  }

  useEffect(() => {
    if (treeId) {
      loadTreeAndSession()
    }
  }, [treeId])

  const loadTreeAndSession = async () => {
    setIsLoading(true)
    setError(null)
    try {
      const treeData = await treesApi.get(treeId!)
      setTree(treeData)

      // If resuming a session
      if (locationState?.sessionId) {
        const sessionData = await sessionsApi.get(locationState.sessionId)
        setSession(sessionData)
        setPathTaken(sessionData.path_taken)
        setCurrentNodeId(sessionData.path_taken[sessionData.path_taken.length - 1] || 'root')
        setDecisions(sessionData.decisions as DecisionRecord[])
        setCustomSteps(sessionData.custom_steps || [])
        setTicketNumber(sessionData.ticket_number || '')
        setClientName(sessionData.client_name || '')
        setShowMetadataForm(false)
      }
    } catch (err) {
      setError('Failed to load tree')
      console.error(err)
    } finally {
      setIsLoading(false)
    }
  }

  const startSession = async () => {
    if (!tree) return
    setIsLoading(true)
    try {
      const newSession = await sessionsApi.create({
        tree_id: tree.id,
        ticket_number: ticketNumber || undefined,
        client_name: clientName || undefined,
      })
      setSession(newSession)
      setShowMetadataForm(false)
    } catch (err) {
      setError('Failed to start session')
      console.error(err)
    } finally {
      setIsLoading(false)
    }
  }

  const findNode = (nodeId: string, structure?: TreeStructure): TreeStructure | null => {
    if (!structure) return null
    if (structure.id === nodeId) return structure
    if (structure.children) {
      for (const child of structure.children) {
        const found = findNode(nodeId, child)
        if (found) return found
      }
    }
    return null
  }

  const findCustomStep = (nodeId: string): CustomStep | null => {
    return customSteps.find(cs => cs.id === nodeId) || null
  }

  // Get descendant nodes two levels deep (grandchildren) from a decision node's options.
  // This skips the immediate children (which often mirror the option labels) and shows
  // the actual next-level nodes the user would encounter further down each path.
  const getDescendantNodes = (decisionNodeId: string): DescendantNode[] => {
    const decisionNode = findNode(decisionNodeId, tree?.tree_structure)
    if (!decisionNode || decisionNode.type !== 'decision' || !decisionNode.options) {
      return []
    }

    const descendants: DescendantNode[] = []

    for (const option of decisionNode.options) {
      if (!option.next_node_id) continue
      const childNode = findNode(option.next_node_id, tree?.tree_structure)
      if (!childNode) continue

      // Go one level deeper: get the grandchildren
      if (childNode.type === 'decision' && childNode.options) {
        for (const childOption of childNode.options) {
          if (!childOption.next_node_id) continue
          const grandchild = findNode(childOption.next_node_id, tree?.tree_structure)
          if (!grandchild) continue

          descendants.push({
            id: grandchild.id,
            label: grandchild.question || grandchild.title || 'Untitled',
            type: grandchild.type,
            parentOptionLabel: `${option.label} \u2192 ${childOption.label}`
          })
        }
      } else if (childNode.type === 'action' && childNode.next_node_id) {
        const grandchild = findNode(childNode.next_node_id, tree?.tree_structure)
        if (grandchild) {
          descendants.push({
            id: grandchild.id,
            label: grandchild.question || grandchild.title || 'Untitled',
            type: grandchild.type,
            parentOptionLabel: `${option.label} \u2192 ${childNode.title || 'Action'}`
          })
        }
      }
      // Solution children have no further descendants - skip them
    }

    return descendants
  }

  // Handler functions - defined before hook call to avoid temporal dead zone
  const handleSelectOption = async (_optionId: string, optionLabel: string, nextNodeId: string) => {
    if (!session || !tree) return

    const node = findNode(currentNodeId, tree.tree_structure)
    if (!node) return

    const newDecision: DecisionRecord = {
      node_id: currentNodeId,
      question: node.question || null,
      answer: optionLabel,
      action_performed: null,
      notes: notes || null,
      automation_used: false,
      timestamp: new Date().toISOString(),
      attachments: [],
    }

    const newPath = [...pathTaken, nextNodeId]
    const newDecisions = [...decisions, newDecision]

    setPathTaken(newPath)
    setDecisions(newDecisions)
    setCurrentNodeId(nextNodeId)
    setNotes('')

    // Update session on backend
    try {
      await sessionsApi.update(session.id, {
        path_taken: newPath,
        decisions: newDecisions,
      })
    } catch (err) {
      console.error('Failed to update session:', err)
    }
  }

  const handleContinue = async (actionPerformed?: string) => {
    if (!session || !tree) return

    const node = findNode(currentNodeId, tree.tree_structure)
    if (!node || !node.next_node_id) return

    const newDecision: DecisionRecord = {
      node_id: currentNodeId,
      question: null,
      answer: null,
      action_performed: actionPerformed || node.title || 'Action completed',
      notes: notes || null,
      automation_used: false,
      timestamp: new Date().toISOString(),
      attachments: [],
    }

    const newPath = [...pathTaken, node.next_node_id]
    const newDecisions = [...decisions, newDecision]

    setPathTaken(newPath)
    setDecisions(newDecisions)
    setCurrentNodeId(node.next_node_id)
    setNotes('')

    try {
      await sessionsApi.update(session.id, {
        path_taken: newPath,
        decisions: newDecisions,
      })
    } catch (err) {
      console.error('Failed to update session:', err)
    }
  }

  const handleComplete = async () => {
    if (!session || !tree) return
    setIsCompleting(true)
    setError(null)
    try {
      // Add final decision
      const node = findNode(currentNodeId, tree.tree_structure)
      if (node) {
        const finalDecision: DecisionRecord = {
          node_id: currentNodeId,
          question: null,
          answer: null,
          action_performed: node.title || 'Session completed',
          notes: notes || null,
          automation_used: false,
          timestamp: new Date().toISOString(),
          attachments: [],
        }
        await sessionsApi.update(session.id, {
          decisions: [...decisions, finalDecision],
        })
      }

      await sessionsApi.complete(session.id)
      navigate(`/sessions/${session.id}`)
    } catch (err) {
      console.error('Failed to complete session:', err)
      setError('Failed to complete session. Check console for details.')
    } finally {
      setIsCompleting(false)
    }
  }

  const handleGoBack = () => {
    if (pathTaken.length <= 1) return
    const newPath = pathTaken.slice(0, -1)
    const newDecisions = decisions.slice(0, -1)
    setPathTaken(newPath)
    setDecisions(newDecisions)
    setCurrentNodeId(newPath[newPath.length - 1])
  }

  // Navigate back to a previously-created custom step from the decision node
  const handleNavigateToCustomStep = (customStep: CustomStep) => {
    const newPath = [...pathTaken, customStep.id]
    setPathTaken(newPath)
    setCurrentNodeId(customStep.id)
  }

  // Called when CustomStepModal submits - show action modal instead of inserting directly
  const handleStepCreated = (step: Step | CustomStepDraft, isFromLibrary: boolean) => {
    setPendingStep(step)
    setPendingStepIsFromLibrary(isFromLibrary)
    setShowCustomStepModal(false)
    setShowPostStepModal(true)
  }

  const resetPendingStep = () => {
    setShowPostStepModal(false)
    setPendingStep(null)
    setPendingStepIsFromLibrary(false)
    setIsSavingStep(false)
  }

  // Save to library only, don't insert into session
  const handleSaveForLater = async () => {
    if (!pendingStep) return

    setIsSavingStep(true)
    try {
      if (!pendingStepIsFromLibrary) {
        await stepsApi.create({
          title: pendingStep.title,
          step_type: pendingStep.step_type,
          content: pendingStep.content,
          visibility: 'private',
          tags: pendingStep.tags || []
        })
      }
      resetPendingStep()
    } catch (err) {
      console.error('Failed to save step to library:', err)
      setIsSavingStep(false)
    }
  }

  // Insert into session and show continuation options
  const handleUseNow = async () => {
    if (!pendingStep || !session) return

    setIsSavingStep(true)
    try {
      // Remember where we branched from (for showing descendants later)
      setBranchOriginNodeId(currentNodeId)

      // Create custom step object
      const customStep: CustomStep = {
        id: crypto.randomUUID(),
        inserted_after_node_id: currentNodeId,
        step_data: pendingStep,
        timestamp: new Date().toISOString()
      }

      // Record decision (so it appears in exports)
      const newDecision: DecisionRecord = {
        node_id: customStep.id,
        question: null,
        answer: null,
        action_performed: `Custom Step: ${pendingStep.title}`,
        notes: pendingStep.content.instructions || null,
        automation_used: false,
        timestamp: new Date().toISOString(),
        attachments: []
      }

      // Update state
      const newCustomSteps = [...customSteps, customStep]
      const newDecisions = [...decisions, newDecision]
      const newPath = [...pathTaken, customStep.id]

      setCustomSteps(newCustomSteps)
      setDecisions(newDecisions)
      setPathTaken(newPath)
      setCurrentNodeId(customStep.id)

      // Persist to backend
      await sessionsApi.update(session.id, {
        path_taken: newPath,
        decisions: newDecisions,
        custom_steps: newCustomSteps
      })

      resetPendingStep()

      // Show continuation modal
      setShowContinuationModal(true)
    } catch (err) {
      console.error('Failed to insert custom step:', err)
      setIsSavingStep(false)
    }
  }

  // Save to library AND insert into session
  const handleBoth = async () => {
    if (!pendingStep) return

    setIsSavingStep(true)
    try {
      // Save to library first
      if (!pendingStepIsFromLibrary) {
        await stepsApi.create({
          title: pendingStep.title,
          step_type: pendingStep.step_type,
          content: pendingStep.content,
          visibility: 'private',
          tags: pendingStep.tags || []
        })
      }

      // Then use now (this will handle the rest and reset pending step)
      await handleUseNow()
    } catch (err) {
      console.error('Failed to save and insert step:', err)
      setIsSavingStep(false)
    }
  }

  // Handle selecting a descendant node from continuation modal.
  // Stores the selection so the user can write notes on their custom step first.
  const handleSelectDescendant = (nodeId: string) => {
    setShowContinuationModal(false)
    setBranchOriginNodeId(null)
    setPendingContinuationNodeId(nodeId)
  }

  // Navigate to the previously-selected descendant node
  const handleContinueToDescendant = async () => {
    if (!pendingContinuationNodeId || !session) return

    const newPath = [...pathTaken, pendingContinuationNodeId]
    setPathTaken(newPath)
    setCurrentNodeId(pendingContinuationNodeId)
    setNotes('')
    setPendingContinuationNodeId(null)

    try {
      await sessionsApi.update(session.id, { path_taken: newPath })
    } catch (err) {
      console.error('Failed to update session path:', err)
    }
  }

  // Enter custom branch building mode
  const handleBuildCustomBranch = () => {
    setShowContinuationModal(false)
    setCustomBranchMode(true)
  }

  // Complete session from custom branch mode
  const handleCustomBranchComplete = async () => {
    if (!session) return

    setIsCompleting(true)
    setError(null)

    try {
      // Record completion decision
      const completionDecision: DecisionRecord = {
        node_id: currentNodeId,
        question: null,
        answer: null,
        action_performed: 'Custom Branch Completed',
        notes: notes || 'Issue resolved via custom troubleshooting steps',
        automation_used: false,
        timestamp: new Date().toISOString(),
        attachments: []
      }

      await sessionsApi.update(session.id, {
        decisions: [...decisions, completionDecision]
      })

      await sessionsApi.complete(session.id)

      // Show fork modal if custom steps exist
      if (customSteps.length > 0) {
        setShowForkModal(true)
      } else {
        navigate(`/sessions/${session.id}`)
      }
    } catch (err) {
      console.error('Failed to complete session:', err)
      setError('Failed to complete session. Please try again.')
    } finally {
      setIsCompleting(false)
    }
  }

  // Fork tree with custom branch
  const handleForkTree = async (name: string, description: string) => {
    if (!tree) return

    try {
      // Create a forked tree structure
      // For now, we'll create a simple copy - the custom steps are documented in the session
      const forkedTree = await treesApi.create({
        name,
        description,
        tree_structure: tree.tree_structure, // Base structure
        is_public: false
      })

      navigate(`/trees/${forkedTree.id}/edit`)
    } catch (err) {
      console.error('Failed to fork tree:', err)
      throw err
    }
  }

  // Skip forking and go to session detail
  const handleSkipFork = () => {
    setShowForkModal(false)
    navigate(`/sessions/${session!.id}`)
  }

  // Compute current node for keyboard shortcuts (must be before any returns for hooks rules)
  const currentNode = tree ? findNode(currentNodeId, tree.tree_structure) : null
  const currentCustomStep = findCustomStep(currentNodeId)
  const currentOptions = currentNode?.options || []

  // Keyboard shortcuts - must be called unconditionally (React hooks rules)
  useTreeNavigationShortcuts({
    onSelectOption: (index) => {
      const option = currentOptions[index]
      if (option && session && tree) {
        handleSelectOption(option.id, option.label, option.next_node_id)
      }
    },
    onGoBack: handleGoBack,
    onContinue: () => {
      if (currentNode?.type === 'action' && currentNode.next_node_id) {
        handleContinue()
      } else if (currentNode?.type === 'solution') {
        handleComplete()
      }
    },
    optionCount: currentOptions.length,
    canGoBack: pathTaken.length > 1 && !showMetadataForm && !isLoading,
    canContinue: !showMetadataForm && !isLoading && (currentNode?.type === 'action' || currentNode?.type === 'solution'),
  })

  if (isLoading) {
    return (
      <div className="flex h-64 items-center justify-center">
        <div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" />
      </div>
    )
  }

  if (error || !tree) {
    return (
      <div className="container mx-auto px-4 py-8">
        <div className="rounded-md bg-destructive/10 p-4 text-destructive">
          {error || 'Tree not found'}
        </div>
        <button
          onClick={() => navigate('/trees')}
          className="mt-4 text-primary hover:underline"
        >
          Back to trees
        </button>
      </div>
    )
  }

  // Session metadata form
  if (showMetadataForm) {
    return (
      <div className="container mx-auto max-w-lg px-4 py-8">
        <h1 className="mb-2 text-2xl font-bold text-foreground">{tree.name}</h1>
        <p className="mb-6 text-muted-foreground">{tree.description}</p>

        <div className="space-y-4 rounded-lg border border-border bg-card p-6">
          <h2 className="font-semibold text-card-foreground">Session Details</h2>
          <p className="text-sm text-muted-foreground">
            Optional: Add ticket and client info for easier tracking
          </p>

          <div>
            <label className="block text-sm font-medium text-foreground">
              Ticket Number
            </label>
            <input
              type="text"
              value={ticketNumber}
              onChange={(e) => setTicketNumber(e.target.value)}
              placeholder="e.g., INC0012345"
              className={cn(
                'mt-1 block w-full rounded-md border border-input bg-background px-3 py-2',
                'text-foreground placeholder:text-muted-foreground',
                'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary'
              )}
            />
          </div>

          <div>
            <label className="block text-sm font-medium text-foreground">
              Client Name
            </label>
            <input
              type="text"
              value={clientName}
              onChange={(e) => setClientName(e.target.value)}
              placeholder="e.g., Acme Corp"
              className={cn(
                'mt-1 block w-full rounded-md border border-input bg-background px-3 py-2',
                'text-foreground placeholder:text-muted-foreground',
                'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary'
              )}
            />
          </div>

          <button
            onClick={startSession}
            className={cn(
              'w-full rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground',
              'hover:bg-primary/90'
            )}
          >
            Start Troubleshooting
          </button>
        </div>
      </div>
    )
  }

  if (!currentNode && !currentCustomStep) {
    return (
      <div className="container mx-auto px-4 py-8">
        <div className="rounded-md bg-destructive/10 p-4 text-destructive">
          Invalid tree structure
        </div>
      </div>
    )
  }

  return (
    <div className="flex h-[calc(100vh-4rem)]">
      {/* Main Content */}
      <div className="flex-1 min-w-0 overflow-y-auto px-4 py-8">
      <div className="mx-auto max-w-4xl">
      {/* Header */}
      <div className="mb-6 flex items-center justify-between">
        <div>
          <h1 className="text-xl font-bold text-foreground">{tree.name}</h1>
          {(ticketNumber || clientName) && (
            <p className="text-sm text-muted-foreground">
              {ticketNumber && `Ticket: ${ticketNumber}`}
              {ticketNumber && clientName && ' · '}
              {clientName && `Client: ${clientName}`}
            </p>
          )}
        </div>
        <button
          onClick={() => navigate('/sessions')}
          className="text-sm text-muted-foreground hover:text-foreground"
        >
          Exit
        </button>
      </div>

      {/* Breadcrumb */}
      <div className="mb-6 flex items-center gap-2 overflow-x-auto text-sm">
        {pathTaken.map((nodeId, index) => {
          const node = findNode(nodeId, tree?.tree_structure)
          const customStep = findCustomStep(nodeId)
          const label = node?.question || node?.title || customStep?.step_data.title || nodeId
          return (
            <span key={nodeId} className="flex items-center gap-2 whitespace-nowrap">
              {index > 0 && <span className="text-muted-foreground">→</span>}
              <span
                className={cn(
                  index === pathTaken.length - 1
                    ? 'font-medium text-foreground'
                    : 'text-muted-foreground'
                )}
              >
                {label.length > 30 ? `${label.slice(0, 30)}...` : label}
              </span>
            </span>
          )
        })}
      </div>

      {/* Current Node */}
      <div className="rounded-lg border border-border bg-card p-6 shadow-sm">
        {/* Decision Node */}
        {currentNode && currentNode.type === 'decision' && (
          <>
            <h2 className="mb-2 text-xl font-semibold text-card-foreground">
              {currentNode.question}
            </h2>
            {currentNode.help_text && (
              <div className="mb-4 text-sm text-muted-foreground">
                <MarkdownContent content={currentNode.help_text} />
              </div>
            )}
            <div className="mb-4 space-y-2">
              {currentNode.options?.map((option, index) => (
                <button
                  key={option.id}
                  onClick={() => handleSelectOption(option.id, option.label, option.next_node_id)}
                  className={cn(
                    'w-full rounded-md border border-input p-3 text-left transition-colors',
                    'hover:border-primary hover:bg-accent',
                    'flex items-center gap-3'
                  )}
                >
                  {index < 9 && (
                    <span className="flex h-6 w-6 shrink-0 items-center justify-center rounded bg-muted text-xs font-medium text-muted-foreground">
                      {index + 1}
                    </span>
                  )}
                  <span>{option.label}</span>
                </button>
              ))}
            </div>
            {/* Previously-created custom steps at this node */}
            {customSteps.filter(cs => cs.inserted_after_node_id === currentNodeId).length > 0 && (
              <div className="mt-2 space-y-2">
                <p className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
                  Your Custom Steps
                </p>
                {customSteps
                  .filter(cs => cs.inserted_after_node_id === currentNodeId)
                  .map(cs => (
                    <button
                      type="button"
                      key={cs.id}
                      onClick={() => handleNavigateToCustomStep(cs)}
                      className={cn(
                        'w-full rounded-md border border-purple-300 bg-purple-50 p-3 text-left transition-colors',
                        'hover:border-purple-500 hover:bg-purple-100',
                        'dark:border-purple-700 dark:bg-purple-900/20 dark:hover:border-purple-500 dark:hover:bg-purple-900/40',
                        'flex items-center gap-3'
                      )}
                    >
                      <span className="flex-shrink-0 rounded-full bg-purple-100 px-2 py-0.5 text-xs font-medium text-purple-800 dark:bg-purple-900 dark:text-purple-100">
                        Custom
                      </span>
                      <span>{cs.step_data.title}</span>
                    </button>
                  ))}
              </div>
            )}

            {/* Add Custom Step Button */}
            <button
              onClick={() => setShowCustomStepModal(true)}
              className="mt-2 text-sm text-primary hover:underline"
            >
              + Add Custom Step
            </button>
          </>
        )}

        {/* Custom Step Node */}
        {currentCustomStep && (
          <div className="rounded-lg border border-purple-200 bg-purple-50 p-4 dark:border-purple-800 dark:bg-purple-900/20">
            {/* Custom Step Badge */}
            <span className="mb-2 inline-block rounded-full bg-purple-100 px-2 py-1 text-xs font-medium text-purple-800 dark:bg-purple-900 dark:text-purple-100">
              Custom Step
            </span>

            <h2 className="mb-2 text-xl font-semibold text-card-foreground">
              {currentCustomStep.step_data.title}
            </h2>

            {currentCustomStep.step_data.content.instructions && (
              <div className="mb-4 text-muted-foreground">
                <MarkdownContent content={currentCustomStep.step_data.content.instructions} />
              </div>
            )}

            {currentCustomStep.step_data.content.help_text && (
              <div className="mb-4 rounded bg-blue-500/10 p-3 text-sm">
                <MarkdownContent content={currentCustomStep.step_data.content.help_text} />
              </div>
            )}

            {currentCustomStep.step_data.content.commands && currentCustomStep.step_data.content.commands.length > 0 && (
              <div className="mb-4">
                <p className="mb-2 text-sm font-medium text-foreground">Commands:</p>
                <div className="space-y-2">
                  {currentCustomStep.step_data.content.commands.map((cmd, index) => (
                    <div key={index}>
                      <p className="mb-1 text-xs text-muted-foreground">{cmd.label}</p>
                      <code className="block rounded bg-muted p-2 text-sm font-mono">
                        {cmd.command}
                      </code>
                    </div>
                  ))}
                </div>
              </div>
            )}

            {/* Continue to selected descendant */}
            {pendingContinuationNodeId && !customBranchMode && (() => {
              const targetNode = findNode(pendingContinuationNodeId, tree?.tree_structure)
              const targetLabel = targetNode?.question || targetNode?.title || 'next step'
              return (
                <div className="mt-6 border-t border-purple-200 pt-4 dark:border-purple-700">
                  <button
                    type="button"
                    onClick={handleContinueToDescendant}
                    className={cn(
                      'flex w-full items-center justify-between rounded-md bg-primary px-4 py-3 text-sm font-medium text-primary-foreground',
                      'hover:bg-primary/90'
                    )}
                  >
                    <span>Continue to: {targetLabel.length > 50 ? `${targetLabel.slice(0, 50)}...` : targetLabel}</span>
                    <ArrowRight className="h-4 w-4 flex-shrink-0" />
                  </button>
                </div>
              )
            })()}

            {/* Custom Branch Controls */}
            {customBranchMode && (
              <div className="mt-6 border-t border-purple-200 pt-4 dark:border-purple-700">
                <p className="mb-3 text-sm text-amber-600 dark:text-amber-400">
                  Building custom branch - add steps until the issue is resolved
                </p>
                <div className="flex flex-wrap gap-3">
                  <button
                    onClick={() => setShowCustomStepModal(true)}
                    className={cn(
                      'flex items-center gap-2 rounded-md border border-input px-4 py-2 text-sm font-medium',
                      'bg-background hover:bg-accent hover:text-accent-foreground'
                    )}
                  >
                    <Plus className="h-4 w-4" />
                    Add Another Step
                  </button>
                  <button
                    onClick={handleCustomBranchComplete}
                    disabled={isCompleting}
                    className={cn(
                      'flex items-center gap-2 rounded-md bg-green-600 px-4 py-2 text-sm font-medium text-white',
                      'hover:bg-green-700 disabled:opacity-50'
                    )}
                  >
                    <CheckCircle className="h-4 w-4" />
                    {isCompleting ? 'Completing...' : 'This Solves My Issue'}
                  </button>
                </div>
              </div>
            )}
          </div>
        )}

        {/* Action Node */}
        {currentNode && currentNode.type === 'action' && (
          <>
            <h2 className="mb-2 text-xl font-semibold text-card-foreground">
              {currentNode.title}
            </h2>
            {currentNode.description && (
              <div className="mb-4 text-muted-foreground">
                <MarkdownContent content={currentNode.description} />
              </div>
            )}
            {currentNode.commands && currentNode.commands.length > 0 && (
              <div className="mb-4">
                <p className="mb-2 text-sm font-medium text-foreground">Commands:</p>
                <div className="space-y-1">
                  {currentNode.commands.map((cmd, index) => (
                    <code
                      key={index}
                      className="block rounded bg-muted p-2 text-sm font-mono"
                    >
                      {cmd}
                    </code>
                  ))}
                </div>
              </div>
            )}
            {currentNode.expected_outcome && (
              <p className="mb-4 text-sm text-muted-foreground">
                <strong>Expected outcome:</strong> {currentNode.expected_outcome}
              </p>
            )}
            {currentNode.next_node_id && (
              <button
                onClick={() => handleContinue()}
                className={cn(
                  'rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground',
                  'hover:bg-primary/90'
                )}
              >
                Continue
              </button>
            )}
          </>
        )}

        {/* Solution Node */}
        {currentNode && currentNode.type === 'solution' && (
          <>
            <div className="mb-4 flex items-center gap-2">
              <span className="rounded-full bg-green-100 px-2 py-1 text-xs font-medium text-green-800">
                Solution
              </span>
            </div>
            <h2 className="mb-2 text-xl font-semibold text-card-foreground">
              {currentNode.title}
            </h2>
            {currentNode.description && (
              <div className="mb-4 text-muted-foreground">
                <MarkdownContent content={currentNode.description} />
              </div>
            )}
            {currentNode.resolution_steps && currentNode.resolution_steps.length > 0 && (
              <div className="mb-4">
                <p className="mb-2 text-sm font-medium text-foreground">Resolution steps:</p>
                <ol className="list-inside list-decimal space-y-1 text-sm text-muted-foreground">
                  {currentNode.resolution_steps.map((step, index) => (
                    <li key={index}>{step}</li>
                  ))}
                </ol>
              </div>
            )}
            <button
              onClick={handleComplete}
              disabled={isCompleting}
              className={cn(
                'rounded-md bg-green-600 px-4 py-2 text-sm font-medium text-white',
                'hover:bg-green-700 disabled:opacity-50'
              )}
            >
              {isCompleting ? 'Completing...' : 'Complete Session'}
            </button>
          </>
        )}

        {/* Notes */}
        <div className="mt-6 border-t border-border pt-4">
          <label className="block text-sm font-medium text-foreground">
            Notes (optional)
          </label>
          <textarea
            value={notes}
            onChange={(e) => setNotes(e.target.value)}
            placeholder="Add any notes for this step..."
            rows={2}
            className={cn(
              'mt-1 block w-full rounded-md border border-input bg-background px-3 py-2',
              'text-foreground placeholder:text-muted-foreground',
              'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary'
            )}
          />
        </div>

        {/* Back Button */}
        {pathTaken.length > 1 && (
          <button
            onClick={handleGoBack}
            className="mt-4 text-sm text-muted-foreground hover:text-foreground"
          >
            ← Go back
          </button>
        )}

        {/* Keyboard Shortcuts Hint */}
        {currentNode && (
          <div className="mt-4 border-t border-border pt-3 text-xs text-muted-foreground">
            <span className="font-medium">Keyboard:</span>{' '}
            {currentNode.type === 'decision' && currentOptions.length > 0 && (
              <span>1-{Math.min(currentOptions.length, 9)} select option</span>
            )}
            {pathTaken.length > 1 && <span>, Esc go back</span>}
            {(currentNode.type === 'action' || currentNode.type === 'solution') && (
              <span>, Enter {currentNode.type === 'solution' ? 'complete' : 'continue'}</span>
            )}
          </div>
        )}
      </div>

      {/* Custom Step Modal */}
      <CustomStepModal
        isOpen={showCustomStepModal}
        onClose={() => setShowCustomStepModal(false)}
        onInsertStep={handleStepCreated}
      />

      {/* Post Step Action Modal */}
      {pendingStep && (
        <PostStepActionModal
          isOpen={showPostStepModal}
          onClose={resetPendingStep}
          step={pendingStep}
          onSaveForLater={handleSaveForLater}
          onUseNow={handleUseNow}
          onBoth={handleBoth}
          isFromLibrary={pendingStepIsFromLibrary}
          isSaving={isSavingStep}
        />
      )}

      {/* Continuation Modal */}
      <ContinuationModal
        isOpen={showContinuationModal}
        onClose={() => setShowContinuationModal(false)}
        descendantNodes={branchOriginNodeId ? getDescendantNodes(branchOriginNodeId) : []}
        onSelectNode={handleSelectDescendant}
        onBuildCustomBranch={handleBuildCustomBranch}
      />

      {/* Fork Tree Modal */}
      <ForkTreeModal
        isOpen={showForkModal}
        onClose={() => setShowForkModal(false)}
        originalTreeName={tree?.name || 'Tree'}
        onFork={handleForkTree}
        onSkip={handleSkipFork}
      />
      </div>
      </div>

      {/* Scratchpad Sidebar */}
      {session && (
        <ScratchpadSidebar
          sessionId={session.id}
          initialContent={session.scratchpad ?? ''}
          onSave={handleScratchpadSave}
        />
      )}
    </div>
  )
}

export default TreeNavigationPage
