import { useState, useEffect, useCallback, useRef } from 'react'
import { motion } from 'framer-motion'
import {
  generateCellSequence,
  normalizeAnswer,
  announceToScreenReader,
  type CellInfo,
} from '@/utils/practice'
import { PracticeMatrix } from '@/components/practice/PracticeMatrix'
import { InputArea } from '@/components/practice/InputArea'
import { HintInfo } from '@/components/practice/HintInfo'

type CharStatus = 'pending' | 'correct' | 'error'

export default function ProcessPracticePage() {
  // 生成格子顺序
  const [cellSequence] = useState<CellInfo[]>(() => generateCellSequence())

  // 从 localStorage 加载答题进度
  const loadProgress = useCallback(() => {
    try {
      const saved = localStorage.getItem('practice-progress')
      if (saved) {
        const data = JSON.parse(saved)
        return {
          answeredCells: new Map<string, boolean>(data.answeredCells || []),
          currentCellId: data.currentCellId || cellSequence[0]?.id || null,
        }
      }
    } catch (e) {
      console.error('加载进度失败:', e)
    }
    return {
      answeredCells: new Map<string, boolean>(),
      currentCellId: cellSequence[0]?.id || null,
    }
  }, [cellSequence])

  // 答题状态
  const [answeredCells, setAnsweredCells] = useState<Map<string, boolean>>(
    () => loadProgress().answeredCells
  )
  const [currentCellId, setCurrentCellId] = useState<string | null>(
    () => loadProgress().currentCellId
  )

  // 输入状态
  const [userInput, setUserInput] = useState<string[]>([])
  const [charStatuses, setCharStatuses] = useState<CharStatus[]>([])
  const [isComposing, setIsComposing] = useState(false)
  const isComposingRef = useRef(false)
  const [lastErrorTimestamp, setLastErrorTimestamp] = useState<number | null>(
    null
  )

  // 长按显示答案
  const [showAnswerForCell, setShowAnswerForCell] = useState<{
    cellId: string
    answer: string
    expiresAt: number
  } | null>(null)
  const [inputLocked, setInputLocked] = useState(false)
  const latestInputRef = useRef<string[]>([])

  // 初始化输入框
  useEffect(() => {
    const currentCell = cellSequence.find((c) => c.id === currentCellId)
    if (currentCell) {
      setUserInput(new Array(currentCell.answer.length).fill(''))
      setCharStatuses(new Array(currentCell.answer.length).fill('pending'))
    }
  }, [currentCellId, cellSequence])

  // 同步当前输入快照，供输入法确认后复用
  useEffect(() => {
    latestInputRef.current = userInput
  }, [userInput])

  // 保存答题进度到 localStorage
  useEffect(() => {
    try {
      localStorage.setItem(
        'practice-progress',
        JSON.stringify({
          answeredCells: Array.from(answeredCells.entries()),
          currentCellId,
        })
      )
    } catch (e) {
      console.error('保存进度失败:', e)
    }
  }, [answeredCells, currentCellId])

  // 恢复焦点到第一个空输入框
  const restoreFocus = useCallback(() => {
    setTimeout(() => {
      const inputs = document.querySelectorAll('.practice-input-area input')
      const firstEmptyInput = Array.from(inputs).find(
        (input) => !(input as HTMLInputElement).value
      ) as HTMLInputElement

      if (firstEmptyInput) {
        firstEmptyInput.focus()
      } else {
        // 如果所有输入框都有值，聚焦到第一个
        (inputs[0] as HTMLInputElement)?.focus()
      }
    }, 100)
  }, [])

  // 切换到指定格子
  const switchToCell = useCallback(
    (cell: CellInfo) => {
      setCurrentCellId(cell.id)
      setUserInput(new Array(cell.answer.length).fill(''))
      setCharStatuses(new Array(cell.answer.length).fill('pending'))
      setLastErrorTimestamp(null)

      // 滚动到可见区域
      requestAnimationFrame(() => {
        const element = document.querySelector(
          `[data-cell-id="${cell.id}"]`
        ) as HTMLElement
        element?.scrollIntoView({ behavior: 'smooth', block: 'center' })
      })

      // 延迟聚焦到第一个输入框，确保 DOM 已更新
      setTimeout(() => {
        const firstInput = document.querySelector(
          '.practice-input-area input'
        ) as HTMLInputElement
        firstInput?.focus()
      }, 150)
    },
    []
  )

  // 移动到下一个格子
  const moveToNextCell = useCallback(() => {
    const currentIndex = cellSequence.findIndex((c) => c.id === currentCellId)
    if (currentIndex === -1 || currentIndex === cellSequence.length - 1) return

    const nextCell = cellSequence[currentIndex + 1]
    switchToCell(nextCell)
  }, [currentCellId, cellSequence, switchToCell])

  // 移动到上一个格子
  const moveToPrevCell = useCallback(() => {
    const currentIndex = cellSequence.findIndex((c) => c.id === currentCellId)
    if (currentIndex <= 0) return

    const prevCell = cellSequence[currentIndex - 1]
    switchToCell(prevCell)
  }, [currentCellId, cellSequence, switchToCell])

  // 统一的输入验证逻辑
  const validateInput = useCallback(
    (input: string[]) => {
      const currentCell = cellSequence.find((c) => c.id === currentCellId)
      if (!currentCell || !currentCellId) return

      const originalAnswer = currentCell.answer
      const normalizedInput = normalizeAnswer(
        input.join(''),
        currentCell.type === 'knowledge-area'
      )
      const normalizedAnswer = currentCell.normalizedAnswer
      const normalizeChar = (char: string) =>
        normalizeAnswer(char, false) || char

      const newCharStatuses = input.map((char, i) => {
        if (!char) return 'pending' as CharStatus
        const expectedChar = originalAnswer[i] || ''
        if (!expectedChar) return 'error' as CharStatus
        return normalizeChar(char) === normalizeChar(expectedChar)
          ? ('correct' as CharStatus)
          : ('error' as CharStatus)
      })
      setCharStatuses(newCharStatuses)

      const isComplete =
        input.every((c) => c !== '') && input.length === originalAnswer.length
      const isCorrect = isComplete && normalizedInput === normalizedAnswer

      if (isCorrect) {
        setAnsweredCells((prev) => new Map(prev).set(currentCellId, true))
        setTimeout(() => {
          moveToNextCell()
        }, 300)
      } else if (isComplete) {
        setLastErrorTimestamp(Date.now())
      }
    },
    [cellSequence, currentCellId, moveToNextCell]
  )

  const handleInputChange = useCallback(
    (newInput: string[]) => {
      latestInputRef.current = newInput
      setUserInput(newInput)

      if (isComposingRef.current) return

      validateInput(newInput)
    },
    [validateInput]
  )

  // 输入法状态管理
  const handleCompositionStart = useCallback((_index: number) => {
    isComposingRef.current = true
    setIsComposing(true)
  }, [])

  const handleCompositionEnd = useCallback(
    (index: number, value: string) => {
      isComposingRef.current = false
      setIsComposing(false)
      // 输入法确认后,需要将当前输入框中的所有字符分散到后续输入框
      requestAnimationFrame(() => {
        const currentInput = latestInputRef.current
        const composedText = value
        const newInput = [...currentInput]

        if (composedText) {
          const chars = composedText.split('')
          for (
            let i = 0;
            i < chars.length && index + i < newInput.length;
            i++
          ) {
            newInput[index + i] = chars[i]
          }
        } else {
          newInput[index] = ''
        }

        latestInputRef.current = newInput
        setUserInput(newInput)
        validateInput(newInput)
      })
    },
    [validateInput]
  )

  // 批量粘贴处理
  const handlePaste = useCallback(
    (e: React.ClipboardEvent) => {
      e.preventDefault()
      const pastedText = e.clipboardData.getData('text')
      const currentCell = cellSequence.find((c) => c.id === currentCellId)
      if (!currentCell) return

      // 创建固定长度的数组，不足部分保留为空字符串
      const targetLength = currentCell.answer.length
      const newInput = new Array(targetLength).fill('')
      const chars = pastedText.split('')

      for (let i = 0; i < Math.min(chars.length, targetLength); i++) {
        newInput[i] = chars[i]
      }

      handleInputChange(newInput)
    },
    [currentCellId, cellSequence, handleInputChange]
  )

  // 长按显示答案
  const handleLongPress = useCallback(
    (cellId: string) => {
      const cell = cellSequence.find((c) => c.id === cellId)
      if (!cell) return

      // 显示答案，并设置过期时间
      setShowAnswerForCell({
        cellId,
        answer: cell.answer,
        expiresAt: Date.now() + 3000, // 3秒后自动隐藏
      })

      // 暂时锁定输入区域
      setInputLocked(true)

      // 无障碍通告
      announceToScreenReader('答案已显示')
    },
    [cellSequence]
  )

  const handleLongPressEnd = useCallback(() => {
    // 只有在答案仍显示时才隐藏（避免重复调用）
    if (showAnswerForCell) {
      setShowAnswerForCell(null)
      setInputLocked(false)
      announceToScreenReader('答案已隐藏')
      restoreFocus()
    }
  }, [showAnswerForCell, restoreFocus])

  // 自动过期检查
  useEffect(() => {
    if (!showAnswerForCell) return

    const remainingTime = showAnswerForCell.expiresAt - Date.now()
    if (remainingTime <= 0) {
      setShowAnswerForCell(null)
      setInputLocked(false)
      restoreFocus()
      return
    }

    const timer = setTimeout(() => {
      setShowAnswerForCell(null)
      setInputLocked(false)
      announceToScreenReader('答案已自动隐藏')
      restoreFocus()
    }, remainingTime)

    return () => clearTimeout(timer)
  }, [showAnswerForCell, restoreFocus])

  // 点击格子切换（允许回顾已答对的格子）
  const handleCellClick = useCallback(
    (cellId: string) => {
      const cell = cellSequence.find((c) => c.id === cellId)
      if (cell) {
        switchToCell(cell)
      }
    },
    [cellSequence, switchToCell]
  )

  // 计算 tabIndex
  const getCellTabIndex = useCallback(
    (cellId: string) => {
      return cellId === currentCellId ? 0 : -1
    },
    [currentCellId]
  )

  // 键盘事件监听
  useEffect(() => {
    function handleKeyDown(e: KeyboardEvent) {
      if (e.key === 'Tab') {
        e.preventDefault()
        if (e.shiftKey) {
          moveToPrevCell()
        } else {
          moveToNextCell()
        }
      } else if (e.key === 'Escape') {
        // 清空当前输入
        setUserInput(new Array(userInput.length).fill(''))
        setCharStatuses(new Array(userInput.length).fill('pending'))
      }
    }

    window.addEventListener('keydown', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [moveToNextCell, moveToPrevCell, userInput.length])

  const currentCell = cellSequence.find((c) => c.id === currentCellId)
  const answeredCount = answeredCells.size
  const totalCount = cellSequence.length

  // 清除进度
  const handleClearProgress = useCallback(() => {
    if (confirm('确定要清除所有答题进度吗？')) {
      setAnsweredCells(new Map())
      setCurrentCellId(cellSequence[0]?.id || null)
      localStorage.removeItem('practice-progress')
    }
  }, [cellSequence])

  return (
    <div className="min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col">
      {/* 顶部进度条 */}
      <div className="sticky top-0 z-20 bg-white dark:bg-gray-800 shadow-sm">
        <div className="max-w-7xl mx-auto px-4 py-3">
          <div className="flex items-center justify-between mb-2">
            <h1 className="text-xl font-bold text-gray-900 dark:text-gray-100">
              过程背诵练习
            </h1>
            <div className="flex items-center gap-3">
              <div className="text-sm text-gray-600 dark:text-gray-400">
                进度：{answeredCount} / {totalCount}
              </div>
              <button
                onClick={handleClearProgress}
                className="text-xs px-2 py-1 text-gray-500 dark:text-gray-400 hover:text-red-600 dark:hover:text-red-400 transition-colors"
              >
                清除进度
              </button>
            </div>
          </div>
          <div className="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
            <motion.div
              className="bg-blue-500 h-2 rounded-full"
              initial={{ width: 0 }}
              animate={{
                width: `${(answeredCount / totalCount) * 100}%`,
              }}
              transition={{ duration: 0.3 }}
            />
          </div>
        </div>
      </div>

      {/* 主内容区域 */}
      <div className="flex-1 overflow-y-auto pb-10">
        {/* 矩阵区域 */}
        <div className="max-w-7xl mx-auto py-4">
          <PracticeMatrix
            answeredCells={answeredCells}
            currentCellId={currentCellId}
            showAnswerForCell={showAnswerForCell}
            onLongPress={handleLongPress}
            onLongPressEnd={handleLongPressEnd}
            onCellClick={handleCellClick}
            getCellTabIndex={getCellTabIndex}
          />
        </div>
      </div>

      {/* 底部固定区域（粘附底部，参与文档流） */}
      <div className="sticky bottom-0 bg-white/60 dark:bg-gray-800/60 backdrop-blur-md border-t border-gray-200 dark:border-gray-700 z-10">
        <div className="max-w-7xl mx-auto px-6">
          {/* 输入区域 */}
          <div className="py-4 border-b border-gray-200/50 dark:border-gray-700/50">
            <div className="flex items-center justify-center gap-3">
              <InputArea
                userInput={userInput}
                charStatuses={charStatuses}
                isComposing={isComposing}
                inputLocked={inputLocked}
                lastErrorTimestamp={lastErrorTimestamp}
                onInputChange={handleInputChange}
                onCompositionStart={handleCompositionStart}
                onCompositionEnd={handleCompositionEnd}
                onPaste={handlePaste}
              />

              {/* 查看答案按钮 */}
              <button
                onClick={() => currentCellId && handleLongPress(currentCellId)}
                className="p-2 text-gray-500 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-400 transition-colors"
                title="查看答案（长按格子也可以）"
              >
                <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                </svg>
              </button>
            </div>
          </div>

          {/* 辅助信息区域 */}
          <div className="py-3 px-4 max-h-48 overflow-y-auto">
            <HintInfo currentCell={currentCell} />
          </div>
        </div>
      </div>

      {/* 无障碍通告区域 */}
      <div
        id="aria-live-region"
        className="sr-only"
        aria-live="polite"
        aria-atomic="true"
      />
    </div>
  )
}
