'use client'

import { useState, useRef, useEffect, useCallback } from 'react'
import { Volume2, VolumeX } from 'lucide-react'
import type { MediaItem } from '@/lib/types'

const TAIL_SKIP = 10
const CROSSFADE_DURATION = 3
const VOLUME = 0.4
const FADE_IN_MS = 2000

export default function MusicPlayer({ tracks }: { tracks: MediaItem[] }) {
  const track = tracks[0] ?? null
  const src = track ? `/api/files/${track.filename}` : null

  const audioA = useRef<HTMLAudioElement>(null)
  const audioB = useRef<HTMLAudioElement>(null)
  const activeRef = useRef<'A' | 'B'>('A')
  const fadingRef = useRef(false)
  const startedRef = useRef(false)
  const audibleRef = useRef(false)

  const [userMuted, setUserMuted] = useState(false)
  const [playing, setPlaying] = useState(false)

  const getActive = useCallback(
    () => (activeRef.current === 'A' ? audioA.current : audioB.current),
    [],
  )
  const getInactive = useCallback(
    () => (activeRef.current === 'A' ? audioB.current : audioA.current),
    [],
  )

  // ── Crossfade loop ────────────────────────────────────────────
  const crossfade = useCallback(() => {
    if (fadingRef.current) return
    fadingRef.current = true

    const out = getActive()!
    const inp = getInactive()!
    activeRef.current = activeRef.current === 'A' ? 'B' : 'A'

    inp.currentTime = 0
    inp.volume = 0
    inp.play().catch(() => {})

    const startTime = performance.now()
    const outStartVol = out.volume
    const targetVol = userMuted ? 0 : VOLUME

    const step = () => {
      const t = Math.min((performance.now() - startTime) / (CROSSFADE_DURATION * 1000), 1)
      inp.volume = targetVol * t
      out.volume = outStartVol * (1 - t)
      if (t < 1) {
        requestAnimationFrame(step)
      } else {
        out.pause()
        out.currentTime = 0
        fadingRef.current = false
      }
    }
    requestAnimationFrame(step)
  }, [userMuted, getActive, getInactive])

  // Monitor for crossfade
  useEffect(() => {
    if (!playing || !src) return
    let id: number
    const tick = () => {
      const a = getActive()
      if (a && a.duration) {
        if (a.duration - a.currentTime <= TAIL_SKIP && !fadingRef.current) {
          crossfade()
        }
      }
      id = requestAnimationFrame(tick)
    }
    id = requestAnimationFrame(tick)
    return () => cancelAnimationFrame(id)
  }, [playing, src, getActive, crossfade])

  // Fallback loop
  const handleEnded = useCallback(() => {
    const a = getActive()
    if (a) { a.currentTime = 0; a.play().catch(() => {}) }
  }, [getActive])

  // Sync volume on mute toggle
  useEffect(() => {
    const vol = userMuted ? 0 : VOLUME
    const a = getActive()
    const b = getInactive()
    if (a && !fadingRef.current) a.volume = vol
    if (b && !fadingRef.current && !b.paused) b.volume = vol
  }, [userMuted, getActive, getInactive])

  // ── Fade volume from 0 → VOLUME ──────────────────────────────
  const fadeIn = useCallback(() => {
    if (audibleRef.current) return
    audibleRef.current = true
    const active = activeRef.current === 'A' ? audioA.current : audioB.current
    if (!active) return
    const t0 = performance.now()
    const step = () => {
      const t = Math.min((performance.now() - t0) / FADE_IN_MS, 1)
      if (!fadingRef.current) active.volume = VOLUME * t
      if (t < 1) requestAnimationFrame(step)
    }
    requestAnimationFrame(step)
  }, [])

  // ── Start playback (called directly in gesture handler for mobile) ──
  const startPlayback = useCallback(() => {
    if (startedRef.current) return
    const a = audioA.current
    if (!a) return
    startedRef.current = true
    a.volume = 0
    a.play().then(() => {
      setPlaying(true)
      fadeIn()
    }).catch(() => { startedRef.current = false })
  }, [fadeIn])

  // ── Autoplay ─────────────────────────────────────────────────
  useEffect(() => {
    if (!src || startedRef.current) return
    const a = audioA.current
    if (!a) return

    // Try silent autoplay (desktop allows this)
    a.volume = 0
    a.play().then(() => {
      startedRef.current = true
      setPlaying(true)
      // Playing silently — fade in on first interaction
      const onInteract = () => fadeIn()
      const events = ['scroll', 'click', 'touchstart', 'keydown'] as const
      events.forEach((e) => window.addEventListener(e, onInteract, { once: true, passive: true }))
    }).catch(() => {
      // Blocked (mobile) — start on first gesture
      const onGesture = () => startPlayback()
      const events = ['click', 'touchstart', 'touchend', 'keydown'] as const
      events.forEach((e) => document.addEventListener(e, onGesture, { once: true, passive: true }))
    })
  }, [src, fadeIn, startPlayback])

  if (!track || !src) return null

  return (
    <>
      <audio ref={audioA} src={src} preload="auto" onEnded={handleEnded} />
      <audio ref={audioB} src={src} preload="auto" onEnded={handleEnded} />

      <button
        onClick={() => setUserMuted((m) => !m)}
        className="fixed bottom-6 right-6 z-50 w-14 h-14 rounded-full bg-stone-950/85 backdrop-blur-sm border border-amber-900/20 shadow-lg flex items-center justify-center text-amber-400/60 hover:text-amber-300 transition-colors"
        title={userMuted ? 'Ton an' : 'Ton aus'}
      >
        {userMuted ? <VolumeX size={22} /> : <Volume2 size={22} />}
      </button>
    </>
  )
}
