import { useRef, type CSSProperties } from 'react'
import { SongCard } from './SongCard'
import type { Song } from './types'

type SongCarouselProps = {
  songs: Song[]
  currentIndex: number
  onSelectIndex: (index: number) => void
}

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

function getSignedOffset(currentIndex: number, index: number, length: number): number {
  const raw = index - currentIndex
  if (raw > length / 2) return raw - length
  if (raw < -length / 2) return raw + length
  return raw
}

export function SongCarousel({ songs, currentIndex, onSelectIndex }: SongCarouselProps) {
  const touchStartX = useRef(0)
  const swiped = useRef(false)

  const handleTouchStart = (e: React.TouchEvent) => {
    touchStartX.current = e.touches[0].clientX
    swiped.current = false
  }

  const handleTouchMove = (e: React.TouchEvent) => {
    if (swiped.current) return
    const dx = e.touches[0].clientX - touchStartX.current
    const threshold = 50
    if (Math.abs(dx) > threshold) {
      swiped.current = true
      if (dx < 0) {
        onSelectIndex(wrapIndex(currentIndex + 1, songs.length))
      } else {
        onSelectIndex(wrapIndex(currentIndex - 1, songs.length))
      }
    }
  }

  const center = songs[currentIndex]
  const displayIndexes = [currentIndex]
  const seen = new Set([currentIndex])
  for (let d = 1; d <= 2; d++) {
    const li = wrapIndex(currentIndex - d, songs.length)
    const ri = wrapIndex(currentIndex + d, songs.length)
    if (!seen.has(li)) { displayIndexes.unshift(li); seen.add(li) }
    if (!seen.has(ri)) { displayIndexes.push(ri); seen.add(ri) }
  }

  return (
    <section className="song-carousel" aria-label="Song carousel">
      <div
        className="song-carousel__viewport"
        style={{ '--active-color': center.color } as CSSProperties}
        onTouchStart={handleTouchStart}
        onTouchMove={handleTouchMove}
      >
        {displayIndexes.map((index) => {
          const offset = getSignedOffset(currentIndex, index, songs.length)
          return (
            <SongCard
              key={`${songs[index].title}-${index}`}
              song={songs[index]}
              trackNumber={index + 1}
              offset={offset}
              isActive={offset === 0}
              onClick={() => {
                if (Math.abs(offset) <= 1) onSelectIndex(index)
              }}
            />
          )
        })}
      </div>
    </section>
  )
}
