import React, { createContext, useContext, useRef, useState, useCallback } from 'react'
import type { PlayerContextValue, VideoState, UIState, PlayerSettings, AudioTrack } from '../types'
import type { Translations } from '../i18n'
import { getTranslations, detectBrowserLanguage } from '../i18n'

type SelectedQuality = PlayerSettings['quality']
type SelectedSubtitle = PlayerSettings['subtitle']

interface PlayerContextType extends PlayerContextValue {
  setVideoState: React.Dispatch<React.SetStateAction<VideoState>>
  setUIState: React.Dispatch<React.SetStateAction<UIState>>
  translations: Translations
}

const PlayerContext = createContext<PlayerContextType | null>(null)

// eslint-disable-next-line react-refresh/only-export-components
export const usePlayerContext = () => {
  const context = useContext(PlayerContext)
  if (!context) {
    throw new Error('usePlayerContext must be used within a PlayerProvider')
  }
  return context
}

interface PlayerProviderProps {
  children: React.ReactNode
  initialVolume?: number
  initialMuted?: boolean
  initialPlaybackRate?: number
  language?: string
}

export const PlayerProvider: React.FC<PlayerProviderProps> = ({
  children,
  initialVolume = 1,
  initialMuted = false,
  initialPlaybackRate = 1,
  language,
}) => {
  const videoRef = useRef<HTMLVideoElement | null>(null)
  const containerRef = useRef<HTMLDivElement | null>(null)

  // Get translations based on language prop or browser language
  const translations = getTranslations(language || detectBrowserLanguage())

  const [videoState, setVideoState] = useState<VideoState>({
    playing: false,
    currentTime: 0,
    duration: 0,
    buffered: 0,
    volume: initialVolume,
    muted: initialMuted,
    playbackRate: initialPlaybackRate,
    fullscreen: false,
    pictureInPicture: false,
    loading: false,
    error: null,
    seeking: false,
    isLiveBroadcast: false,
  })

  const [uiState, setUIState] = useState<UIState>({
    controlsVisible: true,
    settingsOpen: false,
    volumeControlOpen: false,
    qualityMenuOpen: false,
    subtitleMenuOpen: false,
  })

  const [settings, setSettings] = useState<PlayerSettings>({
    quality: null,
    subtitle: null,
    audioTrack: null,
    playbackRate: initialPlaybackRate,
  })

  // Video controls
  const play = useCallback(() => {
    videoRef.current?.play()
  }, [])

  const pause = useCallback(() => {
    videoRef.current?.pause()
  }, [])

  const togglePlay = useCallback(() => {
    if (videoState.playing) {
      pause()
    } else {
      play()
    }
  }, [videoState.playing, play, pause])

  const seek = useCallback((time: number) => {
    if (videoRef.current) {
      videoRef.current.currentTime = time
    }
  }, [])

  const setVolume = useCallback((volume: number) => {
    if (videoRef.current) {
      const clampedVolume = Math.max(0, Math.min(1, volume))
      videoRef.current.volume = clampedVolume
      setVideoState((prev) => ({ ...prev, volume: clampedVolume }))
    }
  }, [])

  const toggleMute = useCallback(() => {
    if (videoRef.current) {
      videoRef.current.muted = !videoRef.current.muted
      setVideoState((prev) => ({ ...prev, muted: !prev.muted }))
    }
  }, [])

  const setPlaybackRate = useCallback((rate: number) => {
    if (videoRef.current) {
      videoRef.current.playbackRate = rate
      setVideoState((prev) => ({ ...prev, playbackRate: rate }))
      setSettings((prev) => ({ ...prev, playbackRate: rate }))
    }
  }, [])

  // Fullscreen & PIP
  const toggleFullscreen = useCallback(() => {
    if (!document.fullscreenElement) {
      containerRef.current?.requestFullscreen()
    } else {
      document.exitFullscreen()
    }
  }, [])

  const togglePictureInPicture = useCallback(async () => {
    if (!document.pictureInPictureElement) {
      try {
        await videoRef.current?.requestPictureInPicture()
      } catch (error) {
        if (error instanceof Error) {
          setVideoState((prev) => ({ ...prev, error }))
        }
      }
    } else {
      await document.exitPictureInPicture()
    }
  }, [])

  // UI controls
  const showControls = useCallback(() => {
    setUIState((prev) => ({ ...prev, controlsVisible: true }))
  }, [])

  const hideControls = useCallback(() => {
    setUIState((prev) => ({ ...prev, controlsVisible: false }))
  }, [])

  const toggleSettings = useCallback(() => {
    setUIState((prev) => ({ ...prev, settingsOpen: !prev.settingsOpen }))
  }, [])

  // Settings
  const setQuality = useCallback((quality: SelectedQuality) => {
    setSettings((prev) => ({ ...prev, quality }))
  }, [])

  const setSubtitle = useCallback((subtitle: SelectedSubtitle) => {
    setSettings((prev) => ({ ...prev, subtitle }))
  }, [])

  const setAudioTrack = useCallback((audioTrack: AudioTrack | null) => {
    setSettings((prev) => ({ ...prev, audioTrack }))
  }, [])

  const value: PlayerContextType = {
    videoState,
    uiState,
    settings,
    videoRef,
    containerRef,
    setVideoState,
    setUIState,
    translations,
    play,
    pause,
    togglePlay,
    seek,
    setVolume,
    toggleMute,
    setPlaybackRate,
    toggleFullscreen,
    togglePictureInPicture,
    showControls,
    hideControls,
    toggleSettings,
    setQuality,
    setSubtitle,
    setAudioTrack,
  }

  return <PlayerContext.Provider value={value}>{children}</PlayerContext.Provider>
}
