import { useEffect, useMemo, useRef, useState } from 'react'
import type { CSSProperties } from 'react'
import { useNavigate } from 'react-router-dom'
import { useGameInput } from '../../input/useGameInput'
import { ArcadeDiscoReflect } from '../../components/ArcadeDiscoReflect'
import { ROUTE_PATHS } from '../../app/route-paths'
import { useGameStatsStore } from '../../stores/game-stats/store'
import { useCustomSongsStore } from '../../stores/custom-songs/store'
import { ARHud } from './ARHud'
import { SONGS } from './song-data'
import { SongCarousel } from './SongCarousel'
import { SongInfoBar } from './SongInfoBar'
import { lighten, withAlpha } from './color-utils'
import { useSongPreview } from './useSongPreview'
import { YouTubeAttribution } from '../../components/YouTubeAttribution'
import './SongSelectScreen.css'

function wrapIndex(index: number, length: number): number {
  return (index + length) % length
}

const ARCADE_ACCENT = '#d946ef'
const ARCADE_HIGHLIGHT = '#f0abfc'

export function SongSelectScreen() {
  const navigate = useNavigate()
  const setCurrentSong = useGameStatsStore((state) => state.setCurrentSong)
  const resetStats = useGameStatsStore((state) => state.resetStats)

  const customSongs = useCustomSongsStore((s) => s.songs)
  const customLoaded = useCustomSongsStore((s) => s.loaded)
  const loadStoredSongs = useCustomSongsStore((s) => s.loadStoredSongs)

  useEffect(() => {
    if (!customLoaded) loadStoredSongs()
  }, [customLoaded, loadStoredSongs])

  const allSongs = useMemo(() => [...SONGS, ...customSongs], [customSongs])

  const [currentIndex, setCurrentIndex] = useState(0)
  const activeSong = allSongs[currentIndex] ?? allSongs[0]
  const ytPreviewRef = useRef<HTMLDivElement>(null)

  useSongPreview(activeSong, ytPreviewRef.current)

  const handleConfirm = () => {
    setCurrentSong(activeSong)
    resetStats()
    navigate(ROUTE_PATHS.game)
  }

  useGameInput((action) => {
    if (action === 'LEFT') {
        setCurrentIndex((prev) => wrapIndex(prev - 1, allSongs.length))
    }

    if (action === 'RIGHT') {
      setCurrentIndex((prev) => wrapIndex(prev + 1, allSongs.length))
    }

    if (action === 'BUTTON_A') {
      handleConfirm()
    }
  })

  const cssVars = useMemo(
    () =>
      ({
        '--song-color': activeSong.color,
        '--song-color-soft': withAlpha(activeSong.color, 0.24),
        '--song-color-highlight': lighten(activeSong.color, 0.42),
        '--arcade-accent': ARCADE_ACCENT,
        '--arcade-highlight': ARCADE_HIGHLIGHT,
      }) as CSSProperties,
    [activeSong.color],
  )

  return (
    <main className="song-select-screen" style={cssVars}>
      <div className="song-select-screen__vignette" aria-hidden="true" />
      <ArcadeDiscoReflect />
      <div className="song-select-screen__scanlines" aria-hidden="true" />

      <ARHud
        currentTrack={currentIndex + 1}
        totalTracks={allSongs.length}
        genre={activeSong.genre}
        difficulty={activeSong.difficulty}
      />

      {!activeSong.isCustom && (
        <YouTubeAttribution>
          <div ref={ytPreviewRef} className="song-select-screen__yt-preview" />
        </YouTubeAttribution>
      )}

      <div className="song-select-screen__content">
        <header className="song-select-screen__header">
          <span className="song-select-screen__disco-ball" aria-hidden="true" />
          <h1 className="song-select-screen__title font-title">SONG SELECT</h1>
          <p className="song-select-screen__subtitle font-caption">
            CHOOSE YOUR TRACK · ← → TO BROWSE
          </p>
        </header>

        <SongCarousel
          songs={allSongs}
          currentIndex={currentIndex}
          onSelectIndex={setCurrentIndex}
        />

        <SongInfoBar
          song={activeSong}
          onConfirm={handleConfirm}
        />

        <button
          className="song-select-screen__add-btn font-caption"
          onClick={() => navigate(ROUTE_PATHS.upload)}
        >
          + ADD TRACK
        </button>
      </div>
    </main>
  )
}
