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 [estado, setEstado] = useState<EstadoJuego>({
    isSpinning: false,
    rotacion: 0,
    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(0)

  // ─── 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,
          }
        }

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

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

  /**
   * Busca la siguiente pregunta disponible.
   * 1. Intenta usar la categoría donde cayó la ruleta (si le quedan preguntas).
   * 2. Si no, recorre las demás categorías en orden circular.
   * 3. Retorna null si ya se usaron las 12 preguntas.
   */
  function obtenerSiguientePregunta(
    catIndice: number,
    usadasPorCat: Record<number, number>,
    pool: Record<number, Pregunta[]>,
  ): { pregunta: Pregunta; categoria: Categoria } | null {
    // Recorrer desde catIndice en círculo
    for (let vuelta = 0; vuelta < SECCIONES; vuelta++) {
      const idx = (catIndice + vuelta) % SECCIONES
      const cat = categorias[idx]
      const usadas = usadasPorCat[cat.id] ?? 0
      const preguntasCat = pool[cat.id] ?? []
      if (usadas < preguntasCat.length) {
        return { pregunta: preguntasCat[usadas], categoria: cat }
      }
    }
    return null
  }

  function girar() {
    if (estado.isSpinning || estado.completado) return

    sounds.wheelSpin?.play()

    const vueltas = 3 + Math.random() * 2
    const anguloFinal = Math.random() * 360
    const rotacionTotal = rotacionRef.current + vueltas * 360 + anguloFinal
    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

      setEstado((prev) => {
        const resultado = obtenerSiguientePregunta(
          indiceCategoria,
          prev.preguntasUsadasPorCategoria,
          prev.preguntasPool,
        )

        if (!resultado) {
          // Ya no hay preguntas — marcar como completado
          return {
            ...prev,
            completado: true,
            aprobado: prev.correctas >= MIN_CORRECTAS,
          }
        }

        return {
          ...prev,
          preguntaActual: resultado.pregunta,
          categoriaActual: resultado.categoria,
          tiempoRestante: TIEMPO_LIMITE,
        }
      })
    }, 4000)
  }

  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() {
    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 }
}
