import { useState, useEffect, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { IconArrowRight, IconArrowDown, IconMessage2Filled, IconCheck, IconX } from '@tabler/icons-react'
import { motion, AnimatePresence } from 'motion/react'
import { useStore } from '../store'
import * as api from '../api'
import Tooltip from './ui/Tooltip'
import type { Direction } from '../types'

export default function CluePanel() {
  const puzzle = useStore((s) => s.puzzle)
  const activeClue = useStore((s) => s.activeClue)
  const direction = useStore((s) => s.direction)
  const wordSpans = useStore((s) => s.wordSpans)
  const selectCell = useStore((s) => s.selectCell)
  const solved = useStore((s) => s.solved)
  const entries = useStore((s) => s.entries)
  const gameMode = useStore((s) => s.gameMode)
  const listRef = useRef<HTMLDivElement>(null)
  const [viewTab, setViewTab] = useState<Direction>(direction)
  const [editingClue, setEditingClue] = useState<number | null>(null)
  const [clueText, setClueText] = useState('')
  const [submitting, setSubmitting] = useState(false)
  const { t } = useTranslation()
  const [submitted, setSubmitted] = useState<Set<number>>(new Set())

  useEffect(() => {
    setViewTab(direction)
  }, [direction])

  useEffect(() => {
    if (!activeClue || !listRef.current) return
    const el = listRef.current.querySelector('.clue-item.active')
    if (el) {
      el.scrollIntoView({ block: 'nearest', behavior: 'smooth' })
    }
  }, [activeClue, direction])

  if (!puzzle) return null

  const clues = viewTab === 'across' ? puzzle.clues_across : puzzle.clues_down

  const isBlind = gameMode === 'blind' && !solved

  const isWordFilled = (num: number): boolean => {
    const span = wordSpans.find(s => s.number === num && s.direction === viewTab)
    if (!span) return false
    return span.cells.every(([r, c]) => entries[r]?.[c])
  }

  const getWordForClue = (num: number): string => {
    const span = wordSpans.find(s => s.number === num && s.direction === viewTab)
    if (!span) return ''
    return span.cells.map(([r, c]) => entries[r]?.[c] || '').join('')
  }

  const onClueClick = (num: number) => {
    const span = wordSpans.find(
      (s) => s.number === num && s.direction === viewTab,
    )
    if (span && span.cells.length > 0) {
      selectCell(span.cells[0][0], span.cells[0][1])
    }
  }

  const startEdit = (num: number) => {
    setEditingClue(num)
    setClueText('')
  }

  const cancelEdit = () => {
    setEditingClue(null)
    setClueText('')
  }

  const submitClue = async (num: number) => {
    const word = getWordForClue(num)
    if (!word || !clueText.trim()) return
    setSubmitting(true)
    try {
      await api.submitClue(word, clueText.trim())
      setSubmitted(prev => new Set(prev).add(num))
      setEditingClue(null)
      setClueText('')
    } catch { /* ignored */ }
    setSubmitting(false)
  }

  return (
    <div className={`clue-panel ${solved ? 'clue-panel-solved' : ''}`} role="region" aria-label="Clues" aria-live="polite">
      <div className="clue-tabs" role="tablist">
        <button
          className={`clue-tab ${viewTab === 'across' ? 'active' : ''}`}
          onClick={() => setViewTab('across')}
          role="tab"
          aria-selected={viewTab === 'across'}
          aria-controls="clue-tabpanel"
          id="clue-tab-across"
        >
          <IconArrowRight size={11} style={{ verticalAlign: -1, marginRight: 4 }} aria-hidden="true" />{t('game.across')}
        </button>
        <button
          className={`clue-tab ${viewTab === 'down' ? 'active' : ''}`}
          onClick={() => setViewTab('down')}
          role="tab"
          aria-selected={viewTab === 'down'}
          aria-controls="clue-tabpanel"
          id="clue-tab-down"
        >
          <IconArrowDown size={11} style={{ verticalAlign: -1, marginRight: 4 }} aria-hidden="true" />{t('game.down')}
        </button>
      </div>
      <div className="clue-list" ref={listRef} role="tabpanel" id="clue-tabpanel"
        aria-labelledby={`clue-tab-${viewTab}`}>
        {clues.map((clue) => (
          <div key={clue.number}>
            <button type="button"
              className={`clue-item ${activeClue === clue.number && direction === viewTab ? 'active' : ''}`}
              onClick={() => onClueClick(clue.number)}
            >
              <span className="clue-num">{clue.number}</span>
              <span className="clue-text">
                {isBlind && !(activeClue === clue.number && direction === viewTab) && !isWordFilled(clue.number)
                  ? <span className="clue-hidden">- - -</span>
                  : <>
                      {clue.text}
                      {clue.wordplay_type && (
                        <span className="clue-wordplay-tag">{clue.wordplay_type}</span>
                      )}
                    </>
                }
              </span>
              <AnimatePresence>
                {solved && !submitted.has(clue.number) && editingClue !== clue.number && (
                  <Tooltip text={t('game.suggestClue')}>
                    <motion.button
                      className="clue-suggest-btn"
                      onClick={e => { e.stopPropagation(); startEdit(clue.number) }}
                      aria-label={t('game.suggestClue')}
                      initial={{ opacity: 0, scale: 0 }}
                      animate={{ opacity: 1, scale: 1 }}
                      exit={{ opacity: 0, scale: 0 }}
                      transition={{ duration: 0.2, delay: clue.number * 0.02 }}
                    >
                      <IconMessage2Filled size={12} aria-hidden="true" />
                    </motion.button>
                  </Tooltip>
                )}
                {submitted.has(clue.number) && (
                  <motion.span
                    className="clue-submitted"
                    initial={{ opacity: 0, scale: 0 }}
                    animate={{ opacity: 1, scale: 1 }}
                    transition={{ duration: 0.2 }}
                  >
                    <IconCheck size={12} />
                  </motion.span>
                )}
              </AnimatePresence>
            </button>
            <AnimatePresence>
              {editingClue === clue.number && (
                <motion.div
                  className="clue-suggest-form"
                  onClick={e => e.stopPropagation()}
                  initial={{ height: 0, opacity: 0 }}
                  animate={{ height: 'auto', opacity: 1 }}
                  exit={{ height: 0, opacity: 0 }}
                  transition={{ duration: 0.2 }}
                  style={{ overflow: 'hidden' }}
                >
                  <div style={{ padding: '0.5rem 1.25rem 0.75rem' }}>
                    <span className="clue-suggest-word">{getWordForClue(clue.number)}</span>
                    <input
                      type="text"
                      placeholder={t('game.clueSubmitPlaceholder')}
                      aria-label={t('game.clueSubmitPlaceholder')}
                      value={clueText}
                      onChange={e => setClueText(e.target.value)}
                      onKeyDown={e => {
                        if (e.key === 'Enter') submitClue(clue.number)
                        if (e.key === 'Escape') cancelEdit()
                      }}
                      maxLength={500}
                      autoFocus
                    />
                    <div className="clue-suggest-actions">
                      <button className="btn btn-sm btn-primary" onClick={() => submitClue(clue.number)} disabled={submitting || !clueText.trim()}>
                        {t('game.submit')}
                      </button>
                      <button className="btn btn-sm btn-ghost" onClick={cancelEdit} aria-label={t('common.cancel')}>
                        <IconX size={12} aria-hidden="true" />
                      </button>
                    </div>
                  </div>
                </motion.div>
              )}
            </AnimatePresence>
          </div>
        ))}
      </div>
    </div>
  )
}
