'use client'

import * as Tooltip from '@radix-ui/react-tooltip'
import {
  type AbacusOverlay,
  AbacusReact,
  type StepBeadHighlight,
  useAbacusDisplay,
} from '@soroban/abacus-react'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { css } from '../../../styled-system/css'
import { hstack, stack, vstack } from '../../../styled-system/patterns'
import type {
  NavigationState,
  Tutorial,
  TutorialEvent,
  TutorialStep,
  UIState,
} from '../../types/tutorial'
import { calculateBeadDiffFromValues } from '../../utils/beadDiff'
import { generateUnifiedInstructionSequence } from '../../utils/unifiedStepGenerator'
import { CoachBar } from './CoachBar/CoachBar'
import { DecompositionWithReasons } from './DecompositionWithReasons'
import { PedagogicalDecompositionDisplay } from './PedagogicalDecompositionDisplay'
import { TutorialProvider, useTutorialContext } from './TutorialContext'
import { TutorialUIProvider } from './TutorialUIContext'
import './CoachBar/coachbar.css'

// Helper function to find the topmost bead with arrows
function findTopmostBeadWithArrows(
  stepBeadHighlights: StepBeadHighlight[] | undefined
): StepBeadHighlight | null {
  if (!stepBeadHighlights || stepBeadHighlights.length === 0) return null

  // Filter only beads that have direction arrows (should have highlights)
  const beadsWithArrows = stepBeadHighlights.filter(
    (bead) => bead.direction && bead.direction !== 'none'
  )

  if (beadsWithArrows.length === 0) {
    console.warn('No beads with arrows found in step highlights:', stepBeadHighlights)
    return null
  }

  // Sort by place value (highest first, since place value 4 = leftmost = highest value)
  // Then by bead type (heaven beads are higher than earth beads)
  // Then by position for earth beads (lower position = higher on abacus)
  const sortedBeads = [...beadsWithArrows].sort((a, b) => {
    // First sort by place value (higher place value = more significant = topmost priority)
    if (a.placeValue !== b.placeValue) {
      return b.placeValue - a.placeValue
    }

    // If same place value, heaven beads come before earth beads
    if (a.beadType !== b.beadType) {
      return a.beadType === 'heaven' ? -1 : 1
    }

    // If both earth beads in same column, lower position number = higher on abacus
    if (a.beadType === 'earth' && b.beadType === 'earth') {
      return (a.position || 0) - (b.position || 0)
    }

    return 0
  })

  return sortedBeads[0] || null
}

// Reducer state and actions
interface TutorialPlayerState {
  currentStepIndex: number
  currentValue: number
  isStepCompleted: boolean
  error: string | null
  events: TutorialEvent[]
  stepStartTime: number
  multiStepStartTime: number // Track when current multi-step started
  uiState: UIState
  currentMultiStep: number // Current step within multi-step instructions (0-based)
}

interface ExpectedStep {
  index: number
  stepIndex: number
  targetValue: number
  startValue: number
  description: string
  mathematicalTerm?: string // Pedagogical term like "10", "(5 - 1)", "-6"
  termPosition?: { startIndex: number; endIndex: number } // Position in full decomposition
}

type TutorialPlayerAction =
  | {
      type: 'INITIALIZE_STEP'
      stepIndex: number
      startValue: number
      stepId: string
    }
  | {
      type: 'USER_VALUE_CHANGE'
      oldValue: number
      newValue: number
      stepId: string
    }
  | { type: 'COMPLETE_STEP'; stepId: string }
  | { type: 'SET_ERROR'; error: string | null }
  | { type: 'ADD_EVENT'; event: TutorialEvent }
  | { type: 'UPDATE_UI_STATE'; updates: Partial<UIState> }
  | { type: 'ADVANCE_MULTI_STEP' }
  | { type: 'PREVIOUS_MULTI_STEP' }
  | { type: 'RESET_MULTI_STEP' }

function _tutorialPlayerReducer(
  state: TutorialPlayerState,
  action: TutorialPlayerAction
): TutorialPlayerState {
  switch (action.type) {
    case 'INITIALIZE_STEP':
      return {
        ...state,
        currentStepIndex: action.stepIndex,
        currentValue: action.startValue,
        isStepCompleted: false,
        error: null,
        stepStartTime: Date.now(),
        multiStepStartTime: Date.now(), // Start timing for first multi-step
        currentMultiStep: 0, // Reset to first multi-step
        events: [
          ...state.events,
          {
            type: 'STEP_STARTED',
            stepId: action.stepId,
            timestamp: new Date(),
          },
        ],
      }

    case 'USER_VALUE_CHANGE':
      return {
        ...state,
        currentValue: action.newValue,
        events: [
          ...state.events,
          {
            type: 'VALUE_CHANGED',
            stepId: action.stepId,
            oldValue: action.oldValue,
            newValue: action.newValue,
            timestamp: new Date(),
          },
        ],
      }

    case 'COMPLETE_STEP':
      return {
        ...state,
        isStepCompleted: true,
        error: null,
        events: [
          ...state.events,
          {
            type: 'STEP_COMPLETED',
            stepId: action.stepId,
            success: true,
            timestamp: new Date(),
          },
        ],
      }

    case 'SET_ERROR':
      return {
        ...state,
        error: action.error,
      }

    case 'ADD_EVENT':
      return {
        ...state,
        events: [...state.events, action.event],
      }

    case 'UPDATE_UI_STATE':
      return {
        ...state,
        uiState: { ...state.uiState, ...action.updates },
      }

    case 'ADVANCE_MULTI_STEP':
      return {
        ...state,
        currentMultiStep: state.currentMultiStep + 1,
        multiStepStartTime: Date.now(), // Reset timer for new multi-step
      }

    case 'PREVIOUS_MULTI_STEP':
      return {
        ...state,
        currentMultiStep: Math.max(0, state.currentMultiStep - 1),
      }

    case 'RESET_MULTI_STEP':
      return {
        ...state,
        currentMultiStep: 0,
      }

    default:
      return state
  }
}

interface TutorialPlayerProps {
  tutorial: Tutorial
  initialStepIndex?: number
  isDebugMode?: boolean
  showDebugPanel?: boolean
  hideNavigation?: boolean
  hideTooltip?: boolean
  silentErrors?: boolean
  abacusColumns?: number
  theme?: 'light' | 'dark'
  onStepChange?: (stepIndex: number, step: TutorialStep) => void
  onStepComplete?: (stepIndex: number, step: TutorialStep, success: boolean) => void
  onTutorialComplete?: (score: number, timeSpent: number) => void
  onEvent?: (event: TutorialEvent) => void
  className?: string
}

function TutorialPlayerContent({
  tutorial,
  initialStepIndex = 0,
  isDebugMode = false,
  showDebugPanel = false,
  hideNavigation = false,
  hideTooltip = false,
  silentErrors = false,
  abacusColumns = 5,
  theme = 'light',
  onStepChange,
  onStepComplete,
  onTutorialComplete,
  onEvent,
  className,
}: TutorialPlayerProps) {
  const [_startTime] = useState(Date.now())
  const isProgrammaticChange = useRef(false)
  const [showHelpForCurrentStep, setShowHelpForCurrentStep] = useState(false)

  // Use tutorial context instead of local state
  const {
    state,
    dispatch,
    currentStep,
    goToStep: contextGoToStep,
    goToNextStep: contextGoToNextStep,
    goToPreviousStep: contextGoToPreviousStep,
    handleValueChange: contextHandleValueChange,
    advanceMultiStep,
    previousMultiStep,
    resetMultiStep,
    activeTermIndices,
    activeIndividualTermIndex,
    getColumnFromTermIndex,
    getGroupTermIndicesFromTermIndex,
    handleAbacusColumnHover,
  } = useTutorialContext()

  const {
    currentStepIndex,
    currentValue,
    isStepCompleted,
    error,
    events,
    stepStartTime,
    multiStepStartTime,
    uiState,
    currentMultiStep,
  } = state

  // Use universal abacus display configuration
  const { config: abacusConfig } = useAbacusDisplay()
  const [isSuccessPopupDismissed, setIsSuccessPopupDismissed] = useState(false)

  // Keep refs needed for step advancement and bead tracking
  const lastValueForStepAdvancement = useRef<number>(currentValue)
  const userHasInteracted = useRef<boolean>(false)
  const lastMovedBead = useRef<StepBeadHighlight | null>(null)

  // Reset success popup when moving to new step
  useEffect(() => {
    setIsSuccessPopupDismissed(false)
  }, [])

  // Auto-dismiss success toast after 3 seconds
  useEffect(() => {
    if (isStepCompleted && !isSuccessPopupDismissed) {
      const timer = setTimeout(() => {
        setIsSuccessPopupDismissed(true)
      }, 3000)
      return () => clearTimeout(timer)
    }
  }, [isStepCompleted, isSuccessPopupDismissed])

  // Current step comes from context
  const beadRefs = useRef<Map<string, SVGElement>>(new Map())

  // Navigation state
  const navigationState: NavigationState = {
    currentStepIndex,
    canGoNext: currentStepIndex < tutorial.steps.length - 1,
    canGoPrevious: currentStepIndex > 0,
    totalSteps: tutorial.steps.length,
    completionPercentage: (currentStepIndex / tutorial.steps.length) * 100,
  }

  // Define the static expected steps using our unified step generator
  const {
    expectedSteps,
    fullDecomposition,
    isMeaningfulDecomposition,
    pedagogicalSegments,
    termPositions,
    unifiedSteps,
  } = useMemo(() => {
    try {
      const unifiedSequence = generateUnifiedInstructionSequence(
        currentStep.startValue,
        currentStep.targetValue
      )

      // Convert unified sequence to expected steps format
      const steps = unifiedSequence.steps.map((step, index) => ({
        index: index,
        stepIndex: index,
        targetValue: step.expectedValue,
        startValue:
          index === 0 ? currentStep.startValue : unifiedSequence.steps[index - 1].expectedValue,
        description: step.englishInstruction,
        mathematicalTerm: step.mathematicalTerm, // Add the pedagogical term
        termPosition: step.termPosition, // Add the precise position information
      }))

      // Extract term positions from steps for DecompositionWithReasons
      const positions = unifiedSequence.steps.map((step) => step.termPosition).filter(Boolean)

      return {
        expectedSteps: steps,
        fullDecomposition: unifiedSequence.fullDecomposition,
        isMeaningfulDecomposition: unifiedSequence.isMeaningfulDecomposition,
        pedagogicalSegments: unifiedSequence.segments,
        termPositions: positions,
        unifiedSteps: unifiedSequence.steps, // NEW: Include the raw unified steps with provenance
      }
    } catch (_error) {
      return {
        expectedSteps: [],
        fullDecomposition: '',
        isMeaningfulDecomposition: false,
        pedagogicalSegments: [],
        termPositions: [],
        unifiedSteps: [], // NEW: Also add empty array for error case
      }
    }
  }, [currentStep.startValue, currentStep.targetValue])

  // Get arrows for the immediate next action to reach current expected step
  const getCurrentStepBeads = useCallback(() => {
    // If no expected steps, fall back to original behavior
    if (expectedSteps.length === 0) return currentStep.stepBeadHighlights

    // Get the current expected step we're working toward
    const currentExpectedStep = expectedSteps[currentMultiStep]

    if (!currentExpectedStep) {
      // If we're past the last step, check if we've reached the final target
      if (currentValue === currentStep.targetValue) {
        return undefined
      }
      return undefined
    }

    // Use the new bead diff algorithm to get arrows for current step
    try {
      const beadDiff = calculateBeadDiffFromValues(currentValue, currentExpectedStep.targetValue)

      if (!beadDiff.hasChanges) {
        return undefined
      }

      // Convert bead diff results to StepBeadHighlight format expected by AbacusReact
      // Filter to only include beads from columns that exist
      const minValidPlaceValue = Math.max(0, 5 - abacusColumns)
      const stepBeadHighlights: StepBeadHighlight[] = beadDiff.changes
        .filter((change) => change.placeValue < abacusColumns)
        .map((change, _index) => ({
          placeValue: change.placeValue,
          beadType: change.beadType,
          position: change.position,
          direction: change.direction,
          stepIndex: currentMultiStep, // Use current multi-step index to match AbacusReact filtering
          order: change.order,
        }))

      return stepBeadHighlights.length > 0 ? stepBeadHighlights : undefined
    } catch (error) {
      console.error('Error generating step beads with bead diff:', error)
      return undefined
    }
  }, [
    currentValue,
    currentStep.targetValue,
    expectedSteps,
    currentMultiStep,
    currentStep.stepBeadHighlights,
    abacusColumns,
  ])

  // Get the current step's bead diff summary for real-time user feedback
  const getCurrentStepSummary = useCallback(() => {
    if (expectedSteps.length === 0) return null

    const currentExpectedStep = expectedSteps[currentMultiStep]
    if (!currentExpectedStep) return null

    try {
      const beadDiff = calculateBeadDiffFromValues(currentValue, currentExpectedStep.targetValue)
      return beadDiff.hasChanges ? beadDiff.summary : null
    } catch (_error) {
      return null
    }
  }, [currentValue, expectedSteps, currentMultiStep])

  // Get current step beads (dynamic arrows for static expected steps)
  const currentStepBeads = getCurrentStepBeads()

  // Get current step summary for real-time user feedback
  const currentStepSummary = getCurrentStepSummary()

  // Filter highlightBeads to only include valid columns
  const filteredHighlightBeads = useMemo(() => {
    if (!currentStep.highlightBeads) return undefined
    return currentStep.highlightBeads.filter((highlight) => {
      return highlight.placeValue < abacusColumns
    })
  }, [currentStep.highlightBeads, abacusColumns])

  // Helper function to highlight the current mathematical term in the full decomposition
  const renderHighlightedDecomposition = useCallback(() => {
    if (!fullDecomposition || expectedSteps.length === 0) return null

    const currentStep = expectedSteps[currentMultiStep]
    if (!currentStep?.mathematicalTerm) return null

    const mathTerm = currentStep.mathematicalTerm

    // Try to use precise position first
    if (currentStep.termPosition) {
      const { startIndex, endIndex } = currentStep.termPosition
      const highlighted = fullDecomposition.substring(startIndex, endIndex)

      // Validate that the highlighted text makes sense
      if (highlighted.includes(mathTerm.replace('-', '')) || highlighted === mathTerm) {
        return {
          before: fullDecomposition.substring(0, startIndex),
          highlighted,
          after: fullDecomposition.substring(endIndex),
        }
      }
    }

    // Fallback: search for the mathematical term in the decomposition
    const searchTerm = mathTerm.startsWith('-') ? mathTerm.substring(1) : mathTerm
    const searchIndex = fullDecomposition.indexOf(searchTerm)

    if (searchIndex !== -1) {
      const startIndex = mathTerm.startsWith('-')
        ? // For negative terms, try to include the preceding dash
          Math.max(0, searchIndex - 1)
        : searchIndex
      const endIndex = mathTerm.startsWith('-')
        ? searchIndex + searchTerm.length
        : searchIndex + mathTerm.length

      return {
        before: fullDecomposition.substring(0, startIndex),
        highlighted: fullDecomposition.substring(startIndex, endIndex),
        after: fullDecomposition.substring(endIndex),
      }
    }

    // Final fallback: highlight the first occurrence of just the number part
    const numberMatch = mathTerm.match(/\d+/)
    if (numberMatch) {
      const number = numberMatch[0]
      const numberIndex = fullDecomposition.indexOf(number)
      if (numberIndex !== -1) {
        return {
          before: fullDecomposition.substring(0, numberIndex),
          highlighted: fullDecomposition.substring(numberIndex, numberIndex + number.length),
          after: fullDecomposition.substring(numberIndex + number.length),
        }
      }
    }

    return null
  }, [fullDecomposition, expectedSteps, currentMultiStep])

  // Create overlay for tooltip positioned precisely at topmost bead using smart collision detection
  const tooltipOverlay = useMemo(() => {
    // Show tooltip if step is completed AND still at target value OR if we have step instructions
    const showCelebration = isStepCompleted && currentValue === currentStep.targetValue
    const showInstructions = !showCelebration && currentStepSummary && currentStepBeads?.length

    if (!showCelebration && !showInstructions) {
      return null
    }

    let topmostBead: StepBeadHighlight | null = null

    if (showCelebration) {
      // For celebration, use the last moved bead or fallback
      if (lastMovedBead.current) {
        topmostBead = lastMovedBead.current
      } else {
        // Use the ones place (rightmost column) heaven bead as fallback
        topmostBead = {
          placeValue: 0, // Ones place
          beadType: 'heaven' as const,
          position: 0,
          direction: 'none' as const,
          stepIndex: currentMultiStep,
          order: 0,
        }
      }
    } else if (showInstructions) {
      // For instructions, use the topmost bead with arrows
      topmostBead = findTopmostBeadWithArrows(currentStepBeads)
    }

    if (!topmostBead) {
      return null
    }

    // Validate that the bead is from a column that exists
    if (topmostBead.placeValue >= abacusColumns) {
      // Bead is from an invalid column, skip tooltip
      return null
    }

    // Smart positioning logic: avoid covering active beads
    // Convert placeValue to columnIndex based on actual number of columns
    const targetColumnIndex = abacusColumns - 1 - topmostBead.placeValue

    // Check if there are any active beads (against reckoning bar OR with arrows) in columns to the left
    const hasActiveBeadsToLeft = (() => {
      // Get current abacus state - we need to check which beads are against the reckoning bar
      const abacusDigits = currentValue
        .toString()
        .padStart(abacusColumns, '0')
        .split('')
        .map(Number)

      for (let col = 0; col < targetColumnIndex; col++) {
        const placeValue = abacusColumns - 1 - col // Convert columnIndex back to placeValue
        const digitValue = abacusDigits[col]

        // Check if any beads are active (against reckoning bar) in this column
        if (digitValue >= 5) {
          // Heaven bead is active
          return true
        }
        if (digitValue % 5 > 0) {
          // Earth beads are active
          return true
        }

        // Also check if this column has beads with direction arrows (from current step)
        const hasArrowsInColumn =
          currentStepBeads?.some((bead) => {
            const beadColumnIndex = abacusColumns - 1 - bead.placeValue
            return beadColumnIndex === col && bead.direction && bead.direction !== 'none'
          }) ?? false
        if (hasArrowsInColumn) {
          return true
        }
      }

      return false
    })()

    // Determine tooltip position and target
    const shouldPositionAbove = hasActiveBeadsToLeft
    const tooltipSide = shouldPositionAbove ? 'top' : 'left'
    const tooltipTarget = shouldPositionAbove
      ? {
          // Target the heaven bead position for the column
          type: 'bead' as const,
          columnIndex: targetColumnIndex,
          beadType: 'heaven' as const,
          beadPosition: 0, // Heaven beads are always at position 0
        }
      : {
          // Target the actual bead
          type: 'bead' as const,
          columnIndex: targetColumnIndex,
          beadType: topmostBead.beadType,
          beadPosition: topmostBead.position,
        }

    // Create an overlay that positions tooltip to avoid covering active beads
    const overlay: AbacusOverlay = {
      id: 'bead-tooltip',
      type: 'tooltip',
      target: tooltipTarget,
      content: (
        <Tooltip.Provider>
          <Tooltip.Root open={true}>
            <Tooltip.Trigger asChild>
              <div style={{ width: '1px', height: '1px', opacity: 0 }} />
            </Tooltip.Trigger>
            <Tooltip.Portal>
              <Tooltip.Content
                side={tooltipSide}
                align="center"
                sideOffset={20}
                style={{
                  background: showCelebration
                    ? 'linear-gradient(135deg, rgba(34, 197, 94, 0.95) 0%, rgba(21, 128, 61, 0.95) 100%)'
                    : '#1e40af',
                  color: 'white',
                  padding: '12px 16px',
                  borderRadius: '8px',
                  fontSize: '14px',
                  fontWeight: '700',
                  boxShadow: showCelebration
                    ? '0 8px 25px rgba(34, 197, 94, 0.4), 0 0 0 2px rgba(255, 255, 255, 0.2)'
                    : '0 4px 12px rgba(0,0,0,0.3)',
                  whiteSpace: 'normal',
                  maxWidth: '200px',
                  minWidth: '150px',
                  wordBreak: 'break-word',
                  zIndex: 50,
                  opacity: 0.95,
                  transition: 'all 0.3s ease',
                  transform: showCelebration ? 'scale(1.05)' : 'scale(1)',
                  animation: showCelebration ? 'celebrationPulse 0.6s ease-out' : 'none',
                }}
                onMouseEnter={(e) => {
                  e.currentTarget.style.opacity = '1'
                }}
                onMouseLeave={(e) => {
                  e.currentTarget.style.opacity = '0.85'
                }}
              >
                <div style={{ fontSize: '12px', opacity: 0.9 }}>
                  {showCelebration ? (
                    <div
                      style={{
                        display: 'flex',
                        alignItems: 'center',
                        gap: '8px',
                        fontSize: '14px',
                        fontWeight: 'bold',
                      }}
                    >
                      <span style={{ fontSize: '18px' }}>🎉</span>
                      <span>Excellent work!</span>
                    </div>
                  ) : (
                    <>
                      {isMeaningfulDecomposition && (
                        <PedagogicalDecompositionDisplay
                          variant="tooltip"
                          showLabel={true}
                          decomposition={renderHighlightedDecomposition()}
                        />
                      )}
                      <span style={{ fontSize: '18px' }}>💡</span> {currentStepSummary}
                    </>
                  )}
                </div>
                <Tooltip.Arrow
                  style={{
                    fill: showCelebration ? '#15803d' : '#1e40af',
                  }}
                />
              </Tooltip.Content>
            </Tooltip.Portal>
          </Tooltip.Root>
        </Tooltip.Provider>
      ),
      offset: { x: 0, y: 0 },
      visible: true,
    }

    return overlay
  }, [
    currentStepSummary,
    currentStepBeads,
    isStepCompleted,
    currentMultiStep,
    renderHighlightedDecomposition,
    currentValue,
    currentStep,
    isMeaningfulDecomposition,
    abacusColumns,
  ])

  // Timer for smart help detection
  useEffect(() => {
    setShowHelpForCurrentStep(false) // Reset help when step changes

    const timer = setTimeout(() => {
      setShowHelpForCurrentStep(true)
    }, 8000) // 8 seconds

    return () => clearTimeout(timer)
  }, []) // Reset when step changes or timer resets

  // Event logging - now just notifies parent, state is managed by reducer
  const notifyEvent = useCallback(
    (event: TutorialEvent) => {
      onEvent?.(event)
    },
    [onEvent]
  )

  // Navigation functions - declare these first since they're used in useEffects
  // Use context goToStep function instead of local one
  const goToStep = contextGoToStep

  // Use context goToNextStep function instead of local one
  const goToNextStep = contextGoToNextStep

  // Use context goToPreviousStep function instead of local one
  const goToPreviousStep = contextGoToPreviousStep

  // Initialize step on mount only
  useEffect(() => {
    if (currentStep && currentStepIndex === initialStepIndex) {
      // Mark this as a programmatic change to prevent feedback loop
      isProgrammaticChange.current = true

      // Dispatch initialization action
      dispatch({
        type: 'INITIALIZE_STEP',
        stepIndex: currentStepIndex,
        startValue: currentStep.startValue,
        stepId: currentStep.id,
      })

      // Notify parent of step change
      onStepChange?.(currentStepIndex, currentStep)
    }
  }, [
    currentStep,
    currentStepIndex, // Dispatch initialization action
    dispatch,
    initialStepIndex, // Notify parent of step change
    onStepChange,
  ]) // Only run on mount

  // Check if step is completed - only complete when we've gone through all multi-steps AND reached target
  useEffect(() => {
    if (currentStep && currentValue === currentStep.targetValue && !isStepCompleted) {
      // For multi-step problems, only complete when we've finished all expected steps
      const isMultiStepProblem = expectedSteps.length > 0
      const hasFinishedAllMultiSteps = currentMultiStep >= expectedSteps.length - 1

      // Complete the step if:
      // 1. It's not a multi-step problem, OR
      // 2. It's a multi-step problem and we've finished all steps
      if (!isMultiStepProblem || hasFinishedAllMultiSteps) {
        dispatch({ type: 'COMPLETE_STEP', stepId: currentStep.id })
        onStepComplete?.(currentStepIndex, currentStep, true)

        // Auto-advance if enabled
        if (uiState.autoAdvance && navigationState.canGoNext) {
          setTimeout(() => goToNextStep(), 1500)
        }
      }
    }
  }, [
    currentValue,
    currentStep,
    isStepCompleted,
    expectedSteps,
    currentMultiStep,
    uiState.autoAdvance,
    navigationState.canGoNext,
    onStepComplete,
    currentStepIndex,
    goToNextStep,
    dispatch,
  ])

  // These refs are already defined above

  // Check if user completed the current expected step and advance to next expected step
  useEffect(() => {
    const valueChanged = currentValue !== lastValueForStepAdvancement.current

    // Get current expected step
    const currentExpectedStep = expectedSteps[currentMultiStep]

    console.log('🔍 Expected step advancement check:', {
      currentValue,
      lastValue: lastValueForStepAdvancement.current,
      valueChanged,
      userHasInteracted: userHasInteracted.current,
      expectedStepIndex: currentMultiStep,
      expectedStepTarget: currentExpectedStep?.targetValue,
      expectedStepReached: currentExpectedStep
        ? currentValue === currentExpectedStep.targetValue
        : false,
      totalExpectedSteps: expectedSteps.length,
      finalTargetReached: currentValue === currentStep?.targetValue,
    })

    // Only advance if user interacted and we have expected steps
    if (
      valueChanged &&
      userHasInteracted.current &&
      expectedSteps.length > 0 &&
      currentExpectedStep
    ) {
      // Check if user reached the current expected step's target
      if (currentValue === currentExpectedStep.targetValue) {
        const hasMoreExpectedSteps = currentMultiStep < expectedSteps.length - 1

        if (hasMoreExpectedSteps) {
          // Auto-advance to next expected step after a delay
          const timeoutId = setTimeout(() => {
            advanceMultiStep()
            lastValueForStepAdvancement.current = currentValue
          }, 1000)

          return () => clearTimeout(timeoutId)
        }
      }
    }
  }, [currentValue, currentStep, currentMultiStep, expectedSteps, advanceMultiStep])

  // Update the reference when the step changes (not just value changes)
  useEffect(() => {
    lastValueForStepAdvancement.current = currentValue
    // Reset user interaction flag when step changes
    userHasInteracted.current = false
    // Reset last moved bead when step changes
    lastMovedBead.current = null
  }, [currentValue])

  // Notify parent of events when they're added to state
  useEffect(() => {
    if (events.length > 0) {
      const lastEvent = events[events.length - 1]
      notifyEvent(lastEvent)
    }
  }, [events, notifyEvent])

  // Wrap context handleValueChange to track user interaction
  const handleValueChange = useCallback(
    (newValue: number) => {
      // Mark that user has interacted
      userHasInteracted.current = true

      // Try to determine which bead was moved by looking at current step beads
      if (currentStepBeads?.length) {
        // Find the first bead with direction arrows as the likely moved bead
        const likelyMovedBead = findTopmostBeadWithArrows(currentStepBeads)
        if (likelyMovedBead) {
          lastMovedBead.current = likelyMovedBead
        }
      }

      // Call the context's handleValueChange
      contextHandleValueChange(newValue)
    },
    [contextHandleValueChange, currentStepBeads]
  )

  // Cleanup handled by context

  // Value tracking handled by context

  const handleBeadClick = useCallback(
    (beadInfo: any) => {
      dispatch({
        type: 'ADD_EVENT',
        event: {
          type: 'BEAD_CLICKED',
          stepId: currentStep.id,
          beadInfo,
          timestamp: new Date(),
        },
      })

      // Check if this is the correct action
      if (currentStep.highlightBeads && Array.isArray(currentStep.highlightBeads)) {
        const isCorrectBead = currentStep.highlightBeads.some((highlight) => {
          // Get place value from highlight
          const highlightPlaceValue = highlight.placeValue
          // Get place value from bead click event
          const beadPlaceValue = beadInfo.bead ? beadInfo.bead.placeValue : 4 - beadInfo.columnIndex

          return (
            highlightPlaceValue === beadPlaceValue &&
            highlight.beadType === beadInfo.beadType &&
            (highlight.position === undefined || highlight.position === beadInfo.position)
          )
        })

        if (!isCorrectBead && !silentErrors) {
          const errorMessage = "That's not the highlighted bead. Try clicking the highlighted bead."
          dispatch({
            type: 'SET_ERROR',
            error: errorMessage,
          })

          dispatch({
            type: 'ADD_EVENT',
            event: {
              type: 'ERROR_OCCURRED',
              stepId: currentStep.id,
              error: errorMessage,
              timestamp: new Date(),
            },
          })
        } else {
          dispatch({ type: 'SET_ERROR', error: null })
        }
      }
    },
    [currentStep, dispatch]
  )

  const handleBeadRef = useCallback((bead: any, element: SVGElement | null) => {
    const key = `${bead.placeValue}-${bead.type}-${bead.position}`
    if (element) {
      beadRefs.current.set(key, element)
    } else {
      beadRefs.current.delete(key)
    }
  }, [])

  // UI state updaters
  const toggleDebugPanel = useCallback(() => {
    dispatch({
      type: 'UPDATE_UI_STATE',
      updates: { showDebugPanel: !uiState.showDebugPanel },
    })
  }, [uiState.showDebugPanel, dispatch])

  const toggleStepList = useCallback(() => {
    dispatch({
      type: 'UPDATE_UI_STATE',
      updates: { showStepList: !uiState.showStepList },
    })
  }, [uiState.showStepList, dispatch])

  const toggleAutoAdvance = useCallback(() => {
    dispatch({
      type: 'UPDATE_UI_STATE',
      updates: { autoAdvance: !uiState.autoAdvance },
    })
  }, [uiState.autoAdvance, dispatch])

  // Two-level dynamic column highlights: group terms + individual term
  const dynamicColumnHighlights = useMemo(() => {
    console.log('🎨 COMPUTING COLUMN HIGHLIGHTS')
    console.log('  - activeTermIndices:', Array.from(activeTermIndices))
    console.log('  - activeIndividualTermIndex:', activeIndividualTermIndex)

    const highlights: Record<number, any> = {}

    // Level 1: Group highlights (blue glow for all terms in activeTermIndices)
    activeTermIndices.forEach((termIndex) => {
      const columnIndex = getColumnFromTermIndex(termIndex, true) // Use group column (rhsPlace)
      console.log(`  - Group term ${termIndex} maps to column ${columnIndex} (using rhsPlace)`)
      if (columnIndex !== null) {
        highlights[columnIndex] = {
          // Group background glow effect (blue)
          backgroundGlow: {
            fill: 'rgba(59, 130, 246, 0.2)',
            blur: 4,
            spread: 16,
          },
          // Group numeral highlighting
          numerals: {
            color: '#1e40af',
            backgroundColor: 'rgba(219, 234, 254, 0.8)',
            fontWeight: 'bold',
            borderRadius: 4,
            borderWidth: 1,
            borderColor: '#3b82f6',
          },
        }
        console.log(`  🔵 Added BLUE highlight for column ${columnIndex}`)
      }
    })

    // Level 2: Individual term highlight (orange glow, overrides group styling)
    if (activeIndividualTermIndex !== null) {
      const individualColumnIndex = getColumnFromTermIndex(activeIndividualTermIndex, false) // Use individual column (termPlace)
      console.log(
        `  - Individual term ${activeIndividualTermIndex} maps to column ${individualColumnIndex} (using termPlace)`
      )
      if (individualColumnIndex !== null) {
        highlights[individualColumnIndex] = {
          // Individual background glow effect (orange) - overrides group glow
          backgroundGlow: {
            fill: 'rgba(249, 115, 22, 0.3)',
            blur: 6,
            spread: 20,
          },
          // Individual numeral highlighting (orange)
          numerals: {
            color: '#c2410c',
            backgroundColor: 'rgba(254, 215, 170, 0.9)',
            fontWeight: 'bold',
            borderRadius: 6,
            borderWidth: 2,
            borderColor: '#ea580c',
          },
        }
        console.log(
          `  🟠 Added ORANGE highlight for column ${individualColumnIndex} (overriding blue)`
        )
      }
    }

    console.log(
      '🎨 Final highlights:',
      Object.keys(highlights).map((col) => `Column ${col}`)
    )
    return highlights
  }, [activeTermIndices, activeIndividualTermIndex, getColumnFromTermIndex])

  // Memoize custom styles calculation to avoid expensive recalculation on every render
  const customStyles = useMemo(() => {
    // Calculate valid column range based on abacusColumns
    const minValidColumn = 5 - abacusColumns

    // Start with static highlights from step configuration
    const staticHighlights: Record<number, any> = {}

    if (currentStep.highlightBeads && Array.isArray(currentStep.highlightBeads)) {
      currentStep.highlightBeads.forEach((highlight) => {
        // Convert placeValue to columnIndex for AbacusReact compatibility
        const columnIndex = abacusColumns - 1 - highlight.placeValue

        // Skip highlights for columns that don't exist
        if (columnIndex < minValidColumn) {
          return
        }

        // Initialize column if it doesn't exist
        if (!staticHighlights[columnIndex]) {
          staticHighlights[columnIndex] = {}
        }

        // Add the bead style to the appropriate type
        if (highlight.beadType === 'earth' && highlight.position !== undefined) {
          if (!staticHighlights[columnIndex].earth) {
            staticHighlights[columnIndex].earth = {}
          }
          staticHighlights[columnIndex].earth[highlight.position] = {
            fill: '#fbbf24',
            stroke: '#f59e0b',
            strokeWidth: 3,
          }
        } else {
          staticHighlights[columnIndex][highlight.beadType] = {
            fill: '#fbbf24',
            stroke: '#f59e0b',
            strokeWidth: 3,
          }
        }
      })
    }

    // Merge static and dynamic highlights (dynamic takes precedence)
    const mergedHighlights = { ...staticHighlights }
    Object.keys(dynamicColumnHighlights).forEach((columnIndexStr) => {
      const columnIndex = parseInt(columnIndexStr, 10)

      // Skip highlights for columns that don't exist
      if (columnIndex < minValidColumn) {
        return
      }

      if (!mergedHighlights[columnIndex]) {
        mergedHighlights[columnIndex] = {}
      }
      // Merge dynamic highlights into the column
      Object.assign(mergedHighlights[columnIndex], dynamicColumnHighlights[columnIndex])
    })

    // Build the custom styles object
    const styles: any = {}

    // Add column highlights if any
    if (Object.keys(mergedHighlights).length > 0) {
      styles.columns = mergedHighlights
    }

    // Add frame styling for dark mode
    if (theme === 'dark') {
      // Column dividers (global for all columns)
      styles.columnPosts = {
        fill: 'rgba(255, 255, 255, 0.3)', // High contrast fill for visibility
        stroke: 'rgba(255, 255, 255, 0.2)',
        strokeWidth: 2,
      }
      // Reckoning bar (horizontal middle bar)
      styles.reckoningBar = {
        fill: 'rgba(255, 255, 255, 0.4)', // High contrast fill for visibility
        stroke: 'rgba(255, 255, 255, 0.25)',
        strokeWidth: 3,
      }
    }

    return Object.keys(styles).length > 0 ? styles : undefined
  }, [currentStep.highlightBeads, dynamicColumnHighlights, abacusColumns, theme])

  if (!currentStep) {
    return <div>No steps available</div>
  }

  return (
    <div
      className={`${css({
        display: 'flex',
        flexDirection: 'column',
        height: '100%',
        minHeight: hideNavigation ? 'auto' : '600px',
      })} ${className || ''}`}
    >
      {/* Header */}
      {!hideNavigation && (
        <div
          className={css({
            borderBottom: '1px solid',
            borderColor: theme === 'dark' ? 'rgba(255, 255, 255, 0.1)' : 'gray.200',
            p: 4,
            bg: theme === 'dark' ? 'rgba(30, 30, 40, 0.6)' : 'white',
          })}
        >
          <div
            className={hstack({
              justifyContent: 'space-between',
              alignItems: 'center',
            })}
          >
            <div>
              <h1 className={css({ fontSize: 'xl', fontWeight: 'bold' })}>{tutorial.title}</h1>
              <p className={css({ fontSize: 'sm', color: 'gray.600' })}>
                Step {currentStepIndex + 1} of {tutorial.steps.length}: {currentStep.title}
              </p>
            </div>

            <div className={hstack({ gap: 2 })}>
              {isDebugMode && (
                <>
                  <button
                    onClick={toggleDebugPanel}
                    className={css({
                      px: 3,
                      py: 1,
                      fontSize: 'sm',
                      border: '1px solid',
                      borderColor: 'blue.300',
                      borderRadius: 'md',
                      bg: uiState.showDebugPanel ? 'blue.100' : 'white',
                      color: 'blue.700',
                      cursor: 'pointer',
                      _hover: { bg: 'blue.50' },
                    })}
                  >
                    Debug
                  </button>
                  <button
                    onClick={toggleStepList}
                    className={css({
                      px: 3,
                      py: 1,
                      fontSize: 'sm',
                      border: '1px solid',
                      borderColor: 'gray.300',
                      borderRadius: 'md',
                      bg: uiState.showStepList ? 'gray.100' : 'white',
                      cursor: 'pointer',
                      _hover: { bg: 'gray.50' },
                    })}
                  >
                    Steps
                  </button>

                  {/* Multi-step navigation controls */}
                  {currentStep.multiStepInstructions &&
                    currentStep.multiStepInstructions.length > 1 && (
                      <>
                        <div
                          className={css({
                            fontSize: 'xs',
                            color: 'gray.600',
                            px: 2,
                            borderLeft: '1px solid',
                            borderColor: 'gray.300',
                            ml: 2,
                            pl: 3,
                          })}
                        >
                          Multi-Step: {currentMultiStep + 1} /{' '}
                          {currentStep.multiStepInstructions.length}
                        </div>
                        <button
                          onClick={() => dispatch({ type: 'RESET_MULTI_STEP' })}
                          disabled={currentMultiStep === 0}
                          className={css({
                            px: 2,
                            py: 1,
                            fontSize: 'xs',
                            border: '1px solid',
                            borderColor: currentMultiStep === 0 ? 'gray.200' : 'orange.300',
                            borderRadius: 'md',
                            bg: currentMultiStep === 0 ? 'gray.100' : 'white',
                            color: currentMultiStep === 0 ? 'gray.400' : 'orange.700',
                            cursor: currentMultiStep === 0 ? 'not-allowed' : 'pointer',
                            _hover: currentMultiStep === 0 ? {} : { bg: 'orange.50' },
                          })}
                        >
                          ⏮ First
                        </button>
                        <button
                          onClick={() => previousMultiStep()}
                          disabled={currentMultiStep === 0}
                          className={css({
                            px: 2,
                            py: 1,
                            fontSize: 'xs',
                            border: '1px solid',
                            borderColor: currentMultiStep === 0 ? 'gray.200' : 'orange.300',
                            borderRadius: 'md',
                            bg: currentMultiStep === 0 ? 'gray.100' : 'white',
                            color: currentMultiStep === 0 ? 'gray.400' : 'orange.700',
                            cursor: currentMultiStep === 0 ? 'not-allowed' : 'pointer',
                            _hover: currentMultiStep === 0 ? {} : { bg: 'orange.50' },
                          })}
                        >
                          ⏪ Prev
                        </button>
                        <button
                          onClick={() => advanceMultiStep()}
                          disabled={
                            currentMultiStep >= currentStep.multiStepInstructions.length - 1
                          }
                          className={css({
                            px: 2,
                            py: 1,
                            fontSize: 'xs',
                            border: '1px solid',
                            borderColor:
                              currentMultiStep >= currentStep.multiStepInstructions.length - 1
                                ? 'gray.200'
                                : 'green.300',
                            borderRadius: 'md',
                            bg:
                              currentMultiStep >= currentStep.multiStepInstructions.length - 1
                                ? 'gray.100'
                                : 'white',
                            color:
                              currentMultiStep >= currentStep.multiStepInstructions.length - 1
                                ? 'gray.400'
                                : 'green.700',
                            cursor:
                              currentMultiStep >= currentStep.multiStepInstructions.length - 1
                                ? 'not-allowed'
                                : 'pointer',
                            _hover:
                              currentMultiStep >= currentStep.multiStepInstructions.length - 1
                                ? {}
                                : { bg: 'green.50' },
                          })}
                        >
                          Next ⏩
                        </button>
                      </>
                    )}
                  <label className={hstack({ gap: 2, fontSize: 'sm' })}>
                    <input
                      type="checkbox"
                      checked={uiState.autoAdvance}
                      onChange={toggleAutoAdvance}
                    />
                    Auto-advance
                  </label>
                </>
              )}
            </div>
          </div>

          {/* Progress bar */}
          <div className={css({ mt: 2, bg: 'gray.200', borderRadius: 'full', h: 2 })}>
            <div
              className={css({
                bg: 'blue.500',
                h: 'full',
                borderRadius: 'full',
                transition: 'width 0.3s ease',
              })}
              style={{ width: `${navigationState.completionPercentage}%` }}
            />
          </div>
        </div>
      )}

      <div className={hstack({ flex: 1, gap: 0 })}>
        {/* Step list sidebar */}
        {uiState.showStepList && (
          <div
            className={css({
              w: '300px',
              borderRight: '1px solid',
              borderColor: 'gray.200',
              bg: 'gray.50',
              p: 4,
              overflowY: 'auto',
            })}
          >
            <h3 className={css({ fontWeight: 'bold', mb: 3 })}>Tutorial Steps</h3>
            <div className={stack({ gap: 2 })}>
              {tutorial.steps && Array.isArray(tutorial.steps) ? (
                tutorial.steps.map((step, index) => (
                  <button
                    key={step.id}
                    onClick={() => goToStep(index)}
                    className={css({
                      p: 3,
                      textAlign: 'left',
                      border: '1px solid',
                      borderColor: index === currentStepIndex ? 'blue.300' : 'gray.200',
                      borderRadius: 'md',
                      bg: index === currentStepIndex ? 'blue.50' : 'white',
                      cursor: 'pointer',
                      _hover: {
                        bg: index === currentStepIndex ? 'blue.100' : 'gray.50',
                      },
                    })}
                  >
                    <div className={css({ fontSize: 'sm', fontWeight: 'medium' })}>
                      {index + 1}. {step.title}
                    </div>
                    <div
                      className={css({
                        fontSize: 'xs',
                        color: 'gray.600',
                        mt: 1,
                      })}
                    >
                      {step.problem}
                    </div>
                  </button>
                ))
              ) : (
                <div
                  className={css({
                    color: 'gray.500',
                    textAlign: 'center',
                    py: 4,
                  })}
                >
                  No tutorial steps available
                </div>
              )}
            </div>
          </div>
        )}

        {/* Main content */}
        <div className={css({ flex: 1, display: 'flex', flexDirection: 'column' })}>
          {/* Step content */}
          <div className={css({ flex: 1, p: 6 })}>
            <div className={vstack({ gap: 6, alignItems: 'center' })}>
              {/* Step instructions */}
              <div className={css({ textAlign: 'center', maxW: '600px' })}>
                <h2
                  className={css({
                    fontSize: '2xl',
                    fontWeight: 'bold',
                    mb: 2,
                    color: theme === 'dark' ? 'gray.200' : 'gray.900',
                  })}
                >
                  {currentStep.problem}
                </h2>
                <p
                  className={css({
                    fontSize: 'lg',
                    color: theme === 'dark' ? 'gray.400' : 'gray.700',
                    mb: 4,
                  })}
                >
                  {currentStep.description}
                </p>
                {/* Hide action description for multi-step problems since it duplicates pedagogical decomposition */}
                {!currentStep.multiStepInstructions && (
                  <p className={css({ fontSize: 'md', color: 'blue.600' })}>
                    {currentStep.actionDescription}
                  </p>
                )}
              </div>

              {/* Multi-step instructions panel */}
              {!hideTooltip &&
                currentStep.multiStepInstructions &&
                currentStep.multiStepInstructions.length > 0 && (
                  <div
                    className={css({
                      p: 5,
                      background:
                        theme === 'dark'
                          ? 'linear-gradient(135deg, rgba(40,40,50,0.6) 0%, rgba(50,50,60,0.6) 50%, rgba(60,50,70,0.3) 100%)'
                          : 'linear-gradient(135deg, rgba(255,248,225,0.95) 0%, rgba(254,252,232,0.95) 50%, rgba(255,245,157,0.15) 100%)',
                      backdropFilter: 'blur(10px)',
                      border:
                        theme === 'dark'
                          ? '1px solid rgba(255,255,255,0.1)'
                          : '1px solid rgba(251,191,36,0.3)',
                      borderRadius: 'xl',
                      boxShadow:
                        theme === 'dark'
                          ? '0 4px 16px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.05)'
                          : '0 8px 32px rgba(251,191,36,0.1), 0 2px 8px rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.6)',
                      position: 'relative',
                      maxW: '600px',
                      w: 'full',
                      '&::before': {
                        content: '""',
                        position: 'absolute',
                        inset: '0',
                        borderRadius: 'xl',
                        background:
                          theme === 'dark'
                            ? 'linear-gradient(135deg, rgba(100,100,120,0.1) 0%, rgba(80,60,100,0.05) 100%)'
                            : 'linear-gradient(135deg, rgba(251,191,36,0.1) 0%, rgba(168,85,247,0.05) 100%)',
                        zIndex: -1,
                      },
                    })}
                  >
                    <p
                      className={css({
                        fontSize: 'base',
                        fontWeight: '600',
                        color: theme === 'dark' ? 'gray.300' : 'amber.900',
                        mb: 4,
                        letterSpacing: 'wide',
                        textShadow: theme === 'dark' ? 'none' : '0 1px 2px rgba(0,0,0,0.1)',
                      })}
                    >
                      Guidance
                    </p>

                    {/* Pedagogical decomposition with interactive reasoning */}
                    {fullDecomposition && isMeaningfulDecomposition && (
                      <div
                        className={css({
                          mb: 4,
                          p: 3,
                          background:
                            theme === 'dark'
                              ? 'linear-gradient(135deg, rgba(50,50,60,0.4) 0%, rgba(40,40,50,0.5) 100%)'
                              : 'linear-gradient(135deg, rgba(255,255,255,0.8) 0%, rgba(248,250,252,0.9) 100%)',
                          border:
                            theme === 'dark'
                              ? '1px solid rgba(255,255,255,0.1)'
                              : '1px solid rgba(203,213,225,0.4)',
                          borderRadius: 'lg',
                          boxShadow:
                            theme === 'dark'
                              ? '0 1px 4px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.05)'
                              : '0 2px 8px rgba(0,0,0,0.06), inset 0 1px 0 rgba(255,255,255,0.7)',
                          backdropFilter: 'blur(4px)',
                        })}
                      >
                        <div
                          className={css({
                            fontSize: 'base',
                            color: theme === 'dark' ? 'gray.300' : 'slate.800',
                            fontFamily: 'mono',
                            fontWeight: '500',
                            letterSpacing: 'tight',
                            lineHeight: '1.5',
                          })}
                        >
                          <DecompositionWithReasons
                            fullDecomposition={fullDecomposition}
                            termPositions={termPositions}
                            segments={pedagogicalSegments}
                          />
                        </div>
                      </div>
                    )}

                    <div
                      className={css({
                        fontSize: 'sm',
                        color: theme === 'dark' ? 'gray.400' : 'amber.800',
                        fontWeight: '500',
                        lineHeight: '1.6',
                      })}
                    >
                      {(() => {
                        // Only show the current step instruction
                        const currentInstruction =
                          currentStep.multiStepInstructions[currentMultiStep]
                        const _mathTerm = expectedSteps[currentMultiStep]?.mathematicalTerm

                        if (!currentInstruction) return null

                        // Hide "Next Action" when at the expected starting state for this step
                        const isAtExpectedStartingState = (() => {
                          if (currentMultiStep === 0) {
                            // First step: check if current value matches tutorial step start value
                            return currentValue === currentStep.startValue
                          } else {
                            // Subsequent steps: check if current value matches previous step's target
                            const previousStepTarget =
                              expectedSteps[currentMultiStep - 1]?.targetValue
                            return currentValue === previousStepTarget
                          }
                        })()

                        const hasMeaningfulSummary =
                          currentStepSummary && !currentStepSummary.includes('No changes needed')

                        // Only show help if:
                        // 1. Not at expected starting state (user needs to do something)
                        // 2. Has meaningful summary to show
                        // 3. Timer has expired (user appears stuck for 8+ seconds)
                        const _needsAction =
                          !isAtExpectedStartingState &&
                          hasMeaningfulSummary &&
                          showHelpForCurrentStep

                        return (
                          <div>
                            <div
                              className={css({
                                mb: 1,
                                fontWeight: 'bold',
                                color: theme === 'dark' ? 'yellow.200' : 'yellow.900',
                                textShadow:
                                  theme === 'dark' ? '0 0 12px rgba(251, 191, 36, 0.4)' : 'none',
                                fontSize: theme === 'dark' ? 'lg' : 'base',
                              })}
                            >
                              {currentInstruction}
                            </div>
                          </div>
                        )
                      })()}
                    </div>
                  </div>
                )}

              {/* Error message */}
              {error && (
                <div
                  className={css({
                    p: 4,
                    bg: 'red.50',
                    border: '1px solid',
                    borderColor: 'red.200',
                    borderRadius: 'md',
                    color: 'red.700',
                    maxW: '600px',
                  })}
                >
                  {error}
                </div>
              )}

              {/* Success message removed from inline layout - now positioned as overlay */}

              {/* Abacus */}
              <div
                className={css({
                  bg: theme === 'dark' ? 'rgba(30, 30, 40, 0.4)' : 'white',
                  border: '2px solid',
                  borderColor: theme === 'dark' ? 'rgba(255, 255, 255, 0.1)' : 'gray.200',
                  borderRadius: 'lg',
                  p: 6,
                  shadow: theme === 'dark' ? '0 4px 6px rgba(0, 0, 0, 0.3)' : 'lg',
                })}
              >
                <AbacusReact
                  value={currentValue}
                  columns={abacusColumns}
                  interactive={true}
                  animated={true}
                  scaleFactor={2.5}
                  colorScheme={abacusConfig.colorScheme}
                  beadShape={abacusConfig.beadShape}
                  hideInactiveBeads={abacusConfig.hideInactiveBeads}
                  soundEnabled={abacusConfig.soundEnabled}
                  soundVolume={abacusConfig.soundVolume}
                  highlightBeads={filteredHighlightBeads}
                  stepBeadHighlights={currentStepBeads}
                  currentStep={currentMultiStep}
                  showDirectionIndicators={true}
                  customStyles={customStyles}
                  overlays={tooltipOverlay ? [tooltipOverlay] : []}
                  onValueChange={handleValueChange}
                  callbacks={{
                    onBeadClick: handleBeadClick,
                    onBeadRef: handleBeadRef,
                  }}
                />

                {/* Debug info */}
                {isDebugMode && (
                  <div
                    className={css({
                      mt: 4,
                      p: 3,
                      bg: 'purple.50',
                      border: '1px solid',
                      borderColor: 'purple.200',
                      borderRadius: 'md',
                      fontSize: 'xs',
                      fontFamily: 'mono',
                    })}
                  >
                    <div>
                      <strong>Step Debug Info:</strong>
                    </div>
                    <div>Current Multi-Step: {currentMultiStep}</div>
                    <div>Total Steps: {currentStep.totalSteps || 'undefined'}</div>
                    <div>
                      Step Bead Highlights:{' '}
                      {currentStepBeads ? currentStepBeads.length : 'undefined'}
                    </div>
                    <div>
                      Dynamic Recalc: {currentValue} → {currentStep.targetValue}
                    </div>
                    <div>Show Direction Indicators: true</div>
                    <div>
                      Multi-Step Instructions:{' '}
                      {currentStep.multiStepInstructions?.length || 'undefined'}
                    </div>
                    {currentStepBeads && (
                      <div className={css({ mt: 2 })}>
                        <div>
                          <strong>Current Step Beads ({currentMultiStep}):</strong>
                        </div>
                        {currentStepBeads
                          .filter((bead) => bead.stepIndex === currentMultiStep)
                          .map((bead, i) => (
                            <div key={i}>
                              - Place {bead.placeValue} {bead.beadType}{' '}
                              {bead.position !== undefined ? `pos ${bead.position}` : ''} →{' '}
                              {bead.direction}
                            </div>
                          ))}
                      </div>
                    )}
                  </div>
                )}
              </div>

              {/* Tooltip */}
              {!hideTooltip && currentStep.tooltip && (
                <div
                  className={css({
                    maxW: '500px',
                    p: 4,
                    bg: 'yellow.50',
                    border: '1px solid',
                    borderColor: 'yellow.200',
                    borderRadius: 'md',
                  })}
                >
                  <h4
                    className={css({
                      fontWeight: 'bold',
                      color: 'yellow.800',
                      mb: 1,
                    })}
                  >
                    {currentStep.tooltip.content}
                  </h4>
                  <p className={css({ fontSize: 'sm', color: 'yellow.700' })}>
                    {currentStep.tooltip.explanation}
                  </p>
                </div>
              )}
            </div>
          </div>

          {/* Navigation controls */}
          {!hideNavigation && (
            <div
              className={css({
                borderTop: '1px solid',
                borderColor: 'gray.200',
                p: 4,
                bg: 'gray.50',
              })}
            >
              <div className={hstack({ justifyContent: 'space-between' })}>
                <button
                  onClick={goToPreviousStep}
                  disabled={!navigationState.canGoPrevious}
                  className={css({
                    px: 4,
                    py: 2,
                    border: '1px solid',
                    borderColor: 'gray.300',
                    borderRadius: 'md',
                    bg: 'white',
                    cursor: navigationState.canGoPrevious ? 'pointer' : 'not-allowed',
                    opacity: navigationState.canGoPrevious ? 1 : 0.5,
                    _hover: navigationState.canGoPrevious ? { bg: 'gray.50' } : {},
                  })}
                >
                  ← Previous
                </button>

                <div className={css({ fontSize: 'sm', color: 'gray.600' })}>
                  Step {currentStepIndex + 1} of {navigationState.totalSteps}
                </div>

                <button
                  onClick={goToNextStep}
                  disabled={!navigationState.canGoNext && !isStepCompleted}
                  className={css({
                    px: 4,
                    py: 2,
                    border: '1px solid',
                    borderColor:
                      navigationState.canGoNext || isStepCompleted ? 'blue.300' : 'gray.300',
                    borderRadius: 'md',
                    bg: navigationState.canGoNext || isStepCompleted ? 'blue.500' : 'gray.200',
                    color: navigationState.canGoNext || isStepCompleted ? 'white' : 'gray.500',
                    cursor:
                      navigationState.canGoNext || isStepCompleted ? 'pointer' : 'not-allowed',
                    _hover: navigationState.canGoNext || isStepCompleted ? { bg: 'blue.600' } : {},
                  })}
                >
                  {navigationState.canGoNext ? 'Next →' : 'Complete Tutorial'}
                </button>
              </div>
            </div>
          )}
        </div>

        {/* Debug panel */}
        {uiState.showDebugPanel && (
          <div
            className={css({
              w: '400px',
              borderLeft: '1px solid',
              borderColor: 'gray.200',
              bg: 'gray.50',
              p: 4,
              overflowY: 'auto',
            })}
          >
            <h3 className={css({ fontWeight: 'bold', mb: 3 })}>Debug Panel</h3>

            <div className={stack({ gap: 4 })}>
              {/* Current state */}
              <div>
                <h4 className={css({ fontWeight: 'medium', mb: 2 })}>Current State</h4>
                <div
                  className={css({
                    fontSize: 'sm',
                    fontFamily: 'mono',
                    bg: 'white',
                    p: 2,
                    borderRadius: 'md',
                  })}
                >
                  <div>
                    Step: {currentStepIndex + 1}/{navigationState.totalSteps}
                  </div>
                  <div>Value: {currentValue}</div>
                  <div>Target: {currentStep.targetValue}</div>
                  <div>Completed: {isStepCompleted ? 'Yes' : 'No'}</div>
                  <div>Time: {Math.round((Date.now() - stepStartTime) / 1000)}s</div>
                </div>
              </div>

              {/* Event log */}
              <div>
                <h4 className={css({ fontWeight: 'medium', mb: 2 })}>Event Log</h4>
                <div
                  className={css({
                    maxH: '300px',
                    overflowY: 'auto',
                    fontSize: 'xs',
                    fontFamily: 'mono',
                    bg: 'white',
                    border: '1px solid',
                    borderColor: 'gray.200',
                    borderRadius: 'md',
                  })}
                >
                  {events
                    .slice(-20)
                    .reverse()
                    .map((event, index) => (
                      <div
                        key={index}
                        className={css({
                          p: 2,
                          borderBottom: '1px solid',
                          borderColor: 'gray.100',
                        })}
                      >
                        <div
                          className={css({
                            fontWeight: 'bold',
                            color: 'blue.600',
                          })}
                        >
                          {event.type}
                        </div>
                        <div className={css({ color: 'gray.600' })}>
                          {event.timestamp.toLocaleTimeString()}
                        </div>
                        {event.type === 'VALUE_CHANGED' && (
                          <div>
                            {event.oldValue} → {event.newValue}
                          </div>
                        )}
                        {event.type === 'ERROR_OCCURRED' && (
                          <div className={css({ color: 'red.600' })}>{event.error}</div>
                        )}
                      </div>
                    ))}
                </div>
              </div>
            </div>
          </div>
        )}
      </div>

      {/* Add CSS animations */}
      <style jsx>{`
        @keyframes celebrationPulse {
          0% {
            transform: scale(1);
          }
          50% {
            transform: scale(1.1);
          }
          100% {
            transform: scale(1.05);
          }
        }
      `}</style>
    </div>
  )
}

// Export wrapper component with provider
export function TutorialPlayer(props: TutorialPlayerProps) {
  return (
    <TutorialUIProvider canHideCoachBar>
      <TutorialProvider
        tutorial={props.tutorial}
        initialStepIndex={props.initialStepIndex}
        showDebugPanel={props.showDebugPanel}
        onStepChange={props.onStepChange}
        onStepComplete={props.onStepComplete}
        onTutorialComplete={props.onTutorialComplete}
        onEvent={props.onEvent}
      >
        <CoachBar />
        <TutorialPlayerContent {...props} />
      </TutorialProvider>
    </TutorialUIProvider>
  )
}
