import { useState, useRef, useEffect, useMemo } from 'react'
import type { Pregunta, Categoria, PreguntasData } from '../types'
import data from '../data/preguntas.json'
import { sounds } from '../audio/AudioController'

const { categorias } = data as PreguntasData
const MAX_PREGUNTAS = 12
const PREGUNTAS_POR_CATEGORIA = 3
const MIN_CORRECTAS = 10 // 80% de 12 para aprobar
const SECCIONES = categorias.length
const ANGULO_SECCION = 360 / SECCIONES
export const TIEMPO_LIMITE = 30

export interface EstadoJuego {
  isSpinning: boolean
  rotacion: number
  preguntaActual: Pregunta | null
  categoriaActual: Categoria | null
  mostrarFeedback: boolean
  feedbackCorrecto: boolean
  preguntasRespondidas: number
  correctas: number
  completado: boolean
  aprobado: boolean
  /** Cuántas preguntas se han usado ya por categoría (id → conteo) */
  preguntasUsadasPorCategoria: Record<number, number>
  /** Pool de 3 preguntas pre-seleccionadas por categoría (id → preguntas) */
  preguntasPool: Record<number, Pregunta[]>
  tiempoRestante: number
}

/**
 * Pre-selecciona aleatoriamente 3 preguntas de cada categoría.
 * Se ejecuta una sola vez al montar el hook.
 */
function crearPool(): Record<number, Pregunta[]> {
  const pool: Record<number, Pregunta[]> = {}
  for (const cat of categorias) {
    const indices = Array.from({ length: cat.preguntas.length }, (_, i) => i)
    // Fisher‑Yates shuffle
    for (let i = indices.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1))
      ;[indices[i], indices[j]] = [indices[j], indices[i]]
    }
    pool[cat.id] = indices.slice(0, PREGUNTAS_POR_CATEGORIA).map((i) => cat.preguntas[i])
  }
  return pool
}

export function useRuleta() {
  const poolInicial = useMemo(() => crearPool(), [])
  const rotacionInicial = useMemo(() => Math.random() * 360, [])

  const [estado, setEstado] = useState<EstadoJuego>({
    isSpinning: false,
    rotacion: rotacionInicial,
    preguntaActual: null,
    categoriaActual: null,
    mostrarFeedback: false,
    feedbackCorrecto: false,
    preguntasRespondidas: 0,
    correctas: 0,
    completado: false,
    aprobado: false,
    preguntasUsadasPorCategoria: {},
    preguntasPool: poolInicial,
    tiempoRestante: TIEMPO_LIMITE,
  })

  const rotacionRef = useRef(rotacionInicial)
  const isSpinningRef = useRef(false)
  const completadoRef = useRef(false)
  const usadasRef = useRef<Record<number, number>>({})
  const poolRef = useRef(poolInicial)
  const girarRef = useRef<() => void>(() => {})

  useEffect(() => {
    usadasRef.current = estado.preguntasUsadasPorCategoria
    poolRef.current = estado.preguntasPool
    completadoRef.current = estado.completado
  }, [estado.preguntasUsadasPorCategoria, estado.preguntasPool, estado.completado])

  // ─── Temporizador por pregunta ───────────────────────────────────────────
  useEffect(() => {
    if (estado.mostrarFeedback || !estado.preguntaActual || estado.completado) return

    const interval = setInterval(() => {
      setEstado((prev) => {
        if (prev.mostrarFeedback || !prev.preguntaActual) return prev

        if (prev.tiempoRestante <= 1) {
          sounds.incorrect?.play()
          const nuevasRespondidas = prev.preguntasRespondidas + 1
          const completado = nuevasRespondidas >= MAX_PREGUNTAS
          const aprobado = completado && prev.correctas >= MIN_CORRECTAS
          return {
            ...prev,
            tiempoRestante: 0,
            preguntasRespondidas: nuevasRespondidas,
            mostrarFeedback: true,
            feedbackCorrecto: false,
            completado,
            aprobado,
            preguntasUsadasPorCategoria: {
              ...prev.preguntasUsadasPorCategoria,
              ...(prev.categoriaActual
                ? { [prev.categoriaActual.id]: (prev.preguntasUsadasPorCategoria[prev.categoriaActual.id] ?? 0) + 1 }
                : {}),
            },
          }
        }

        return { ...prev, tiempoRestante: prev.tiempoRestante - 1 }
      })
    }, 1000)

    return () => clearInterval(interval)
  }, [estado.preguntaActual?.id, estado.mostrarFeedback, estado.completado])

  function girar() {
    if (isSpinningRef.current || completadoRef.current) return

    const hayDisponibles = categorias.some((cat) => {
      const usadas = usadasRef.current[cat.id] ?? 0
      return usadas < (poolRef.current[cat.id]?.length ?? 0)
    })
    if (!hayDisponibles) {
      setEstado((prev) => ({
        ...prev,
        completado: true,
        aprobado: prev.correctas >= MIN_CORRECTAS,
      }))
      return
    }

    isSpinningRef.current = true
    sounds.wheelSpin?.play()

    const vueltas = 3 + Math.random() * 2
    const anguloExtra = Math.random() * 360
    const delta = vueltas * 360 + anguloExtra
    const rotacionTotal = rotacionRef.current + delta
    rotacionRef.current = rotacionTotal

    setEstado((prev) => ({ ...prev, isSpinning: true, rotacion: rotacionTotal }))

    setTimeout(() => {
      const anguloNormalizado = ((360 - (rotacionRef.current % 360)) + 360) % 360
      const indiceCategoria = Math.floor(anguloNormalizado / ANGULO_SECCION) % SECCIONES
      const cat = categorias[indiceCategoria]
      const usadas = usadasRef.current[cat.id] ?? 0
      const preguntasCat = poolRef.current[cat.id] ?? []

      // Categoría sin preguntas → re-girar
      if (usadas >= preguntasCat.length) {
        isSpinningRef.current = false
        setEstado((prev) => ({ ...prev, isSpinning: false }))
        setTimeout(() => girarRef.current(), 600)
        return
      }

      setEstado((prev) => ({
        ...prev,
        preguntaActual: preguntasCat[usadas],
        categoriaActual: cat,
        tiempoRestante: TIEMPO_LIMITE,
      }))
    }, 4000)
  }

  girarRef.current = girar

  function responder(indiceOpcion: number) {
    if (!estado.preguntaActual || !estado.categoriaActual) return
    const esCorrecta = indiceOpcion === estado.preguntaActual.correcta

    if (esCorrecta) sounds.correct?.play()
    else sounds.incorrect?.play()

    const nuevasCorrectas = estado.correctas + (esCorrecta ? 1 : 0)
    const nuevasRespondidas = estado.preguntasRespondidas + 1
    const completado = nuevasRespondidas >= MAX_PREGUNTAS
    const aprobado = completado && nuevasCorrectas >= MIN_CORRECTAS

    setEstado((prev) => ({
      ...prev,
      correctas: nuevasCorrectas,
      preguntasRespondidas: nuevasRespondidas,
      mostrarFeedback: true,
      feedbackCorrecto: esCorrecta,
      completado,
      aprobado,
      preguntasUsadasPorCategoria: {
        ...prev.preguntasUsadasPorCategoria,
        [prev.categoriaActual!.id]:
          (prev.preguntasUsadasPorCategoria[prev.categoriaActual!.id] ?? 0) + 1,
      },
    }))
  }

  function cerrarFeedback() {
    isSpinningRef.current = false
    setEstado((prev) => ({
      ...prev,
      preguntaActual: null,
      categoriaActual: null,
      mostrarFeedback: false,
      isSpinning: false,
      tiempoRestante: TIEMPO_LIMITE,
    }))
  }

  return { estado, categorias, girar, responder, cerrarFeedback, MAX_PREGUNTAS, MIN_CORRECTAS, TIEMPO_LIMITE }
}
