import { useCallback, useEffect, useMemo, useState } from 'react'
import { globalWords } from '../data/globalWords'
import { API_BASE_URL } from '../config'

const exposuresGoal = 5
const speedOptions = [
  { label: 'Suave', ms: 2600 },
  { label: 'Normal', ms: 1800 },
  { label: 'Turbo', ms: 1100 },
]

const shuffle = <T,>(items: T[]): T[] => {
  const array = [...items]
  for (let i = array.length - 1; i > 0; i -= 1) {
    const j = Math.floor(Math.random() * (i + 1))
    ;[array[i], array[j]] = [array[j], array[i]]
  }
  return array
}

const buildChoices = (palabra: string, total = 4) => {
  const otherWords = globalWords.filter((item) => item.palabra !== palabra).map((item) => item.palabra)
  const randomOthers = shuffle(otherWords).slice(0, total - 1)
  return shuffle([palabra, ...randomOthers])
}

export function GlobalReading() {
  const [currentIndex, setCurrentIndex] = useState(0)
  const [autoPlay, setAutoPlay] = useState(false)
  const [speed, setSpeed] = useState(speedOptions[1].ms)
  const [history, setHistory] = useState<string[]>([])
  const [favorites, setFavorites] = useState<string[]>([])
  const [exposures, setExposures] = useState<Record<string, number>>({})
  const [choices, setChoices] = useState<string[]>(() => buildChoices(globalWords[0].palabra))
  const [selectedChoice, setSelectedChoice] = useState<string | null>(null)
  const [isMatchCorrect, setIsMatchCorrect] = useState<boolean | null>(null)
  const [imageCache, setImageCache] = useState<Record<string, string>>({})
  const [imageStatus, setImageStatus] = useState<Record<string, 'loading' | 'ready' | 'error'>>({})

  const currentWord = globalWords[currentIndex]
  const exposureProgress = (exposures[currentWord.palabra] ?? 0) / exposuresGoal

  const advance = useCallback(() => {
    setCurrentIndex((prevIndex) => {
      const shownWord = globalWords[prevIndex]
      setHistory((prev) => {
        const next = [shownWord.palabra, ...prev.filter((word) => word !== shownWord.palabra)]
        return next.slice(0, 6)
      })
      setExposures((prev) => ({
        ...prev,
        [shownWord.palabra]: Math.min(exposuresGoal, (prev[shownWord.palabra] ?? 0) + 1),
      }))
      return (prevIndex + 1) % globalWords.length
    })
  }, [])

  useEffect(() => {
    setChoices(buildChoices(currentWord.palabra))
    setSelectedChoice(null)
    setIsMatchCorrect(null)
  }, [currentWord.palabra])

  useEffect(() => {
    const slug = currentWord.slug
    setImageCache((prev) => {
      if (prev[slug]) return prev
      const url = `${API_BASE_URL}/global-words/${slug}/image?ts=${Date.now()}`
      return { ...prev, [slug]: url }
    })
    setImageStatus((prev) => {
      if (prev[slug]) return prev
      return { ...prev, [slug]: 'loading' }
    })
  }, [currentWord.slug])

  useEffect(() => {
    if (!autoPlay) return
    const id = window.setInterval(advance, speed)
    return () => window.clearInterval(id)
  }, [autoPlay, advance, speed])

  const goBack = () => {
    setCurrentIndex((prev) => (prev - 1 + globalWords.length) % globalWords.length)
  }

  const toggleFavorite = () => {
    setFavorites((prev) =>
      prev.includes(currentWord.palabra)
        ? prev.filter((word) => word !== currentWord.palabra)
        : [...prev, currentWord.palabra]
    )
  }

  const handleChoice = (option: string) => {
    setSelectedChoice(option)
    setIsMatchCorrect(option === currentWord.palabra)
  }

  const retryImage = () => {
    const slug = currentWord.slug
    const retryUrl = `${API_BASE_URL}/global-words/${slug}/image?ts=${Date.now()}`
    setImageCache((prev) => ({ ...prev, [slug]: retryUrl }))
    setImageStatus((prev) => ({ ...prev, [slug]: 'loading' }))
  }

  const handleImageLoad = () => {
    const slug = currentWord.slug
    setImageStatus((prev) => ({ ...prev, [slug]: 'ready' }))
  }

  const handleImageError = () => {
    const slug = currentWord.slug
    setImageStatus((prev) => ({ ...prev, [slug]: 'error' }))
  }

  const currentImage = imageCache[currentWord.slug]
  const currentImageStatus = imageStatus[currentWord.slug]
  const spelledLetters = useMemo(() => {
    const normalized = currentWord.palabra
      .normalize('NFD')
      .replace(/[\u0300-\u036f]/g, '')
      .replace(/\s+/g, '')
    return normalized.split('').map((char) => char.toUpperCase())
  }, [currentWord.palabra])
  const spelledWord = spelledLetters.join(' ')

  const masteryCount = useMemo(
    () => Object.values(exposures).filter((count) => count >= exposuresGoal).length,
    [exposures]
  )

  return (
    <section className="global-module">
      <div className="global-card">
        <div>
          <p className="chip">Palabra #{currentIndex + 1}</p>
          <div className="word-letter-row" aria-label={currentWord.palabra}>
            {spelledLetters.map((letter, index) => (
              <span key={`title-${letter}-${index}`} className="letter-card big">
                {letter}
              </span>
            ))}
          </div>
          <p className="original-word">{currentWord.palabra}</p>
          <div className="global-tags">
            <span className="chip">{currentWord.categoria}</span>
            <span className="chip">{currentWord.tema}</span>
          </div>
          <div className="global-figure">
            <div className="global-figure-media">
              {currentImage ? (
                <>
                  <img
                    src={currentImage}
                    alt={`Ilustración de ${currentWord.palabra}`}
                    onLoad={handleImageLoad}
                    onError={handleImageError}
                  />
                  {currentImageStatus !== 'ready' && (
                    <span className="image-badge">
                      {currentImageStatus === 'loading'
                        ? 'Generando ilustración...'
                        : 'Error al cargar'}
                    </span>
                  )}
                </>
              ) : (
                <div className="image-placeholder">Generando ilustración...</div>
              )}
            </div>
            <div className="spelling-panel">
              <p className="spelling-label">Así se escribe</p>
              <div className="letter-row" aria-label={`Letras: ${spelledWord}`}>
                {spelledLetters.map((letter, index) => (
                  <span key={`panel-${letter}-${index}`} className="letter-card">
                    {letter}
                  </span>
                ))}
              </div>
              <p className="global-description">{currentWord.descripcion}</p>
              {currentImageStatus === 'error' && (
                <button className="control-button" onClick={retryImage}>
                  Reintentar imagen
                </button>
              )}
            </div>
          </div>
          <div className="global-choices">
            {choices.map((option) => (
              <button
                key={option}
                className={`choice-button ${
                  option === selectedChoice
                    ? isMatchCorrect
                      ? 'correct'
                      : 'incorrect'
                    : ''
                }`}
                onClick={() => handleChoice(option)}
              >
                {option}
              </button>
            ))}
          </div>
          {selectedChoice && (
            <p className={`choice-feedback ${isMatchCorrect ? 'ok' : 'oops'}`}>
              {isMatchCorrect ? '¡Excelente! Encajaste la palabra con la imagen.' : 'Probemos otra vez.'}
            </p>
          )}
          <div className="global-progress">
            <small>
              Exposiciones: {exposures[currentWord.palabra] ?? 0}/{exposuresGoal}
            </small>
            <div className="progress-track" aria-hidden>
              <div className="progress-fill" style={{ width: `${exposureProgress * 100}%` }} />
            </div>
          </div>
        </div>

        <div className="controls-row">
          <button className="control-button" onClick={goBack}>
            ← Volver
          </button>
          <button className="control-button primary" onClick={advance}>
            Siguiente →
          </button>
          <button
            className={`control-button ${autoPlay ? 'active' : ''}`}
            onClick={() => setAutoPlay((prev) => !prev)}
          >
            {autoPlay ? 'Detener ráfaga' : 'Modo ráfaga'}
          </button>
          <button className="control-button" onClick={toggleFavorite}>
            {favorites.includes(currentWord.palabra) ? 'Quitar favorito' : 'Favorito 🚀'}
          </button>
        </div>

        <div>
          <p style={{ margin: '0 0 0.35rem', fontWeight: 700 }}>Velocidad</p>
          <div className="speed-buttons">
            {speedOptions.map((option) => (
              <button
                key={option.label}
                className={`speed-button ${speed === option.ms ? 'active' : ''}`}
                onClick={() => setSpeed(option.ms)}
              >
                {option.label}
              </button>
            ))}
          </div>
        </div>

        <p style={{ margin: 0, fontWeight: 700 }}>
          Palabras dominadas: {masteryCount}/{globalWords.length}
        </p>
      </div>

      <div className="global-lists">
        <div className="panel">
          <h3>Últimas palabras</h3>
          <div className="history-list">
            {history.length === 0 && <span>No hay historial aún.</span>}
            {history.map((item) => (
              <span key={item} className="history-chip">
                {item}
              </span>
            ))}
          </div>
        </div>
        <div className="panel">
          <h3>Favoritas de Milo</h3>
          <div className="favorites-grid">
            {favorites.length === 0 && <span>Toca ⭐ para guardarlas.</span>}
            {favorites.map((word) => (
              <span key={word} className="favorite-chip">
                {word}
              </span>
            ))}
          </div>
        </div>
      </div>
    </section>
  )
}
