import { Fragment, useMemo } from 'react'

import type { MediaPlaylist } from 'hls.js'

import { DebouncedFunc } from 'lodash'

import { isMobileDevice } from 'config/userAgent'

import { secondsToHms } from 'helpers/secondsToHms'

import { ProgressBar as ProgressBarMultiSource } from 'features/MultiSourcePlayer/components/ProgressBar'
import { Chapters as MultiSourceChapters } from 'features/MultiSourcePlayer/types'
import { Chapters as LiveChapters } from 'features/StreamPlayer/types'

import { ControlsMobile } from './Components/ControlsMobile'
import { ControlsWeb } from './Components/ControlsWeb'
import { ProgressBar } from '../ProgressBar'

export type ControlsProps = {
  activeChapterIndex: number,
  activePlayer?: number,
  allPlayedProgress: number,
  audioTracks?: Array<MediaPlaylist>,
  backToLive?: () => void,
  changeAudioTrack?: (trackId: number) => void,
  controlsVisible: boolean,
  duration: number,
  isFirstChapterPlaying?: boolean,
  isFullscreen: boolean,
  isLastChapterPlaying?: boolean,
  isLive?: boolean,
  isStorage?: boolean,
  liveChapters?: LiveChapters,
  loadedProgress: number,
  multiSourceChapters?: MultiSourceChapters,
  muted: boolean,
  numberOfChapters?: number,
  onFullscreenClick: () => void,
  onProgressChange: (progress: number, seeking: boolean) => void,
  onQualitySelect: (quality: string) => void,
  onTouchEnd: DebouncedFunc<() => void>,
  onTouchStart: () => void,
  onVolumeChange: (value: number) => void,
  onVolumeClick: () => void,
  playNextChapter?: (fromMs?: number | undefined, startOffsetMs?: number | undefined) => void,
  playPrevChapter?: (fromMs?: number | undefined, startOffsetMs?: number | undefined) => void,
  playedProgress: number,
  playing: boolean,
  rewindBackward: () => void,
  rewindForward: () => void,
  selectedAudioTrack?: MediaPlaylist,
  selectedQuality: string,
  src?: string,
  togglePlaying: () => void,
  videoQualities: Array<string>,
  videoRef: React.RefObject<HTMLVideoElement>,
  volume: number,
  volumeInPercent: number,
}

export type ControlsPropsExtended = ControlsProps & {
  playBackTime: string,
  progressBarElement: JSX.Element,
}

export const Controls = ({ ...props }: ControlsProps) => {
  const {
    activeChapterIndex = 0,
    allPlayedProgress = 0,
    controlsVisible,
    duration,
    isLive,
    isStorage,
    liveChapters,
    loadedProgress,
    multiSourceChapters,
    onProgressChange,
    onTouchEnd,
    onTouchStart,
    playedProgress,
  } = props

  const playBackTime = useMemo(() => {
    if (isLive || isStorage) {
      return secondsToHms(allPlayedProgress / 1000)
    }
    return `${secondsToHms(allPlayedProgress / 1000)}
    ${' / '}
    ${secondsToHms(duration / 1000)}`
  }, [
    allPlayedProgress,
    duration,
    isLive,
    isStorage,
  ])
  const progressBarElement = useMemo(() => {
    if (isLive || isStorage) {
      return (
        <ProgressBar
          duration={duration}
          isScrubberVisible={controlsVisible}
          onPlayedProgressChange={onProgressChange}
          playedProgress={playedProgress}
          loadedProgress={loadedProgress}
          activeChapterIndex={activeChapterIndex}
          allPlayedProgress={allPlayedProgress}
          chapters={liveChapters!}
        />
      )
    }
    return (
      <ProgressBarMultiSource
        activeChapterIndex={activeChapterIndex}
        allPlayedProgress={allPlayedProgress}
        chapters={multiSourceChapters}
        duration={duration}
        isScrubberVisible={controlsVisible}
        onTouchEnd={onTouchEnd}
        onTouchStart={onTouchStart}
        onPlayedProgressChange={onProgressChange!}
        playedProgress={playedProgress}
        loadedProgress={loadedProgress}
      />
    )
  }, [
    activeChapterIndex,
    allPlayedProgress,
    liveChapters,
    multiSourceChapters,
    controlsVisible,
    duration,
    isLive,
    isStorage,
    loadedProgress,
    onProgressChange,
    onTouchEnd,
    onTouchStart,
    playedProgress,
  ])

  const controlsPropsExtended: ControlsPropsExtended = {
    ...props,
    playBackTime,
    progressBarElement,
  }

  return (
    <Fragment>
      {isMobileDevice
        ? <ControlsMobile props={controlsPropsExtended} />
        : <ControlsWeb props={controlsPropsExtended} />}
    </Fragment>
  )
}
