import { useEffect, useRef } from 'react'
import type { BaseItemDto } from '../api/types'
import { useTrakt } from '../stores/trakt-store'
import { scrobbleStart, scrobblePause, scrobbleStop } from '../lib/trakt'

interface Args {
  item: BaseItemDto | null | undefined
  isPaused: boolean
  currentTime: number
  duration: number
}

/**
 * Fire Trakt scrobble calls in response to local playback transitions.
 *
 * - start on first play
 * - pause on pause
 * - resume sends another start
 * - stop on unmount (covers navigating away mid-playback)
 *
 * Progress + duration are tracked through refs so the stop-on-unmount
 * effect (which only re-binds when the item changes) sees the latest
 * values rather than the ones captured at mount. Scrobble transitions
 * key off `isPaused` only - they shouldn't fire on every time-update tick.
 */
export function useTraktScrobble({ item, isPaused, currentTime, duration }: Args) {
  const tokens = useTrakt(s => s.tokens)
  const enabled = useTrakt(s => s.enabled)
  const lastState = useRef<'idle' | 'playing' | 'paused'>('idle')
  const lastItemId = useRef<string | null>(null)
  const progressRef = useRef({ currentTime: 0, duration: 0 })

  // Keep progress in a ref so cleanup callbacks see the latest value.
  progressRef.current = { currentTime, duration }

  // Reset when item changes
  useEffect(() => {
    if (item?.Id && item.Id !== lastItemId.current) {
      lastState.current = 'idle'
      lastItemId.current = item.Id
    }
  }, [item?.Id])

  // State transitions. Only depends on isPaused - currentTime updates
  // would otherwise re-run this effect dozens of times a second.
  useEffect(() => {
    if (!enabled || !tokens || !item) return
    const { currentTime: t, duration: d } = progressRef.current
    const pct = d > 0 ? (t / d) * 100 : 0
    if (isPaused) {
      if (lastState.current === 'playing') {
        lastState.current = 'paused'
        scrobblePause(item, pct).catch(() => {})
      }
    } else {
      if (lastState.current !== 'playing') {
        lastState.current = 'playing'
        scrobbleStart(item, pct).catch(() => {})
      }
    }
  }, [enabled, tokens, item, isPaused])

  // Stop scrobble on unmount or item swap. Reads progress from the ref
  // so the percentage reflects where the user actually stopped.
  useEffect(() => {
    const captured = item
    return () => {
      if (!useTrakt.getState().enabled) return
      if (!useTrakt.getState().tokens) return
      if (!captured) return
      if (lastState.current === 'idle') return
      const { currentTime: t, duration: d } = progressRef.current
      const pct = d > 0 ? (t / d) * 100 : 0
      scrobbleStop(captured, pct).catch(() => {})
      lastState.current = 'idle'
    }
  }, [item])
}
