import React from 'react'
import PropTypes from 'prop-types'
import {
  StackView,
  useThemeTokens,
  selectSystemProps,
  Icon,
  useViewport
} from '@telus-uds/components-base'

import styled from 'styled-components'
import VideoProgressBar from './Controls/VideoProgressBar/VideoProgressBar'
import VolumeSlider from './Controls/VolumeSlider/VolumeSlider'
import VideoButton from './Controls/VideoButton/VideoButton'
import VideoMenu from './Controls/VideoMenu/VideoMenu'
import videoText from '../videoText'
import { htmlAttrs } from '../../utils'

const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])

const getIcon = (icon) => <Icon icon={icon} />

const ControlBarContainer = styled.div(({ isHidden, isMobile }) => ({
  width: '100%',
  position: 'relative',
  transition: 'opacity 0.4s',
  opacity: isHidden ? 0 : 1,
  display: isMobile ? 'none' : undefined
}))

const StyledControlBar = styled.div(({ padding, height }) => ({
  boxSizing: 'border-box',
  position: 'absolute',
  width: '100%',
  height,
  padding,
  bottom: 0,
  backgroundColor: 'rgba(42, 44, 46, 0.85)', // TODO: replace with opaque greyThunder
  margin: 'auto',
  display: 'flex',
  justifyContent: 'space-between',
  zIndex: 9
}))

const VideoProgressBarContainer = styled.div({
  display: 'flex',
  flexGrow: 1
})

const MenuContainer = styled.div(({ isOpen, menuBottom, menuRight, menuMarginLeft }) => ({
  position: 'absolute',
  bottom: menuBottom,
  right: menuRight,
  display: isOpen ? 'block' : 'none',
  marginLeft: menuMarginLeft
}))

const ControlBar = ({
  videoPlayer,
  videoPlayerContainer,
  sources,
  tracks,
  videoPlaying,
  videoUnplayed,
  videoBufferEnd,
  isHidden = false,
  videoLength,
  videoCurrentTime,
  videoCurrentVolume,
  videoIsMuted,
  setVolume,
  isMobile,
  tracksAvailable,
  togglePlayPause,
  setSeek,
  toggleMute,
  toggleFullscreen,
  videoIsFullscreen,
  setTextTracks,
  selectedTextTrack,
  resetInactivityTimer,
  videoQuality,
  setVideoQuality,
  captionsMenuOpen,
  setCaptionsMenuOpen,
  qualityMenuOpen,
  setQualityMenuOpen,
  clearInactivityTimer,
  copy,
  compactModeThreshold,
  videoPlayerWidth,
  tokens,
  variant,
  ...rest
}) => {
  const viewport = useViewport()
  const {
    paddingTop,
    paddingBottom,
    paddingLeft,
    paddingRight,
    menuBottom,
    menuRight,
    menuMarginLeft,
    captionsIcon,
    settingsIcon,
    minimizeIcon,
    maximizeIcon,
    height
  } = useThemeTokens('VideoControlBar', tokens, variant, { viewport })

  const parseVideoQuality = () => {
    return sources.map((source) => {
      if (!source.isFallback) {
        return { name: source.qualityName, value: source.qualityRank }
      }
      return {}
    })
  }

  const parseTracks = () => {
    const parsed = tracks.map((track, trackNumber) => {
      return { name: videoText[copy][track.language], value: trackNumber }
    })
    parsed.unshift({ name: videoText[copy].captionsNone, value: -1 })
    return parsed
  }

  const menuContainerStyleProps = { menuBottom, menuRight, menuMarginLeft }

  return (
    <ControlBarContainer isHidden={isHidden} isMobile={isMobile} {...selectProps(rest)}>
      <StyledControlBar
        padding={`${paddingTop}px ${paddingRight}px ${paddingBottom}px ${paddingLeft}px`}
        height={`${height}px`}
      >
        <VideoProgressBarContainer>
          <VideoProgressBar
            copy={copy}
            videoPlayer={videoPlayer}
            playing={videoPlaying}
            videoLength={videoLength}
            videoCurrentTime={videoCurrentTime}
            videoBufferEnd={videoBufferEnd}
            setSeek={setSeek}
            resetInactivityTimer={resetInactivityTimer}
          />
        </VideoProgressBarContainer>

        <VolumeSlider
          videoPlayer={videoPlayer}
          videoCurrentVolume={videoCurrentVolume}
          setVolume={setVolume}
          videoIsMuted={videoIsMuted}
          toggleMute={toggleMute}
          resetInactivityTimer={resetInactivityTimer}
          copy={copy}
          compactModeThreshold={compactModeThreshold}
          videoPlayerWidth={videoPlayerWidth}
          disableFocus={videoUnplayed}
        />

        <StackView space={3} direction="row">
          {tracksAvailable && (
            <VideoButton
              disableFocus={videoUnplayed}
              label={videoText[copy].captionsToggle}
              icon={getIcon(captionsIcon)}
              onClick={() => {
                setCaptionsMenuOpen(!captionsMenuOpen)
                setQualityMenuOpen(false)
                clearInactivityTimer()
              }}
              onFocus={resetInactivityTimer}
              onBlur={resetInactivityTimer}
            />
          )}
          <VideoButton
            disableFocus={videoUnplayed}
            label={videoText[copy].qualityToggle}
            icon={getIcon(settingsIcon)}
            onClick={() => {
              setQualityMenuOpen(!qualityMenuOpen)
              setCaptionsMenuOpen(false)
              clearInactivityTimer()
            }}
            onFocus={resetInactivityTimer}
            onBlur={resetInactivityTimer}
          />
          <VideoButton
            disableFocus={videoUnplayed}
            label={videoText[copy].fullScreenToggle}
            icon={videoIsFullscreen ? getIcon(minimizeIcon) : getIcon(maximizeIcon)}
            onClick={toggleFullscreen}
            onFocus={resetInactivityTimer}
            onBlur={resetInactivityTimer}
          />
        </StackView>
        {captionsMenuOpen && (
          <MenuContainer isOpen={captionsMenuOpen} {...menuContainerStyleProps}>
            <VideoMenu
              menuLabel={videoText[copy].captionsDialogue}
              menuOptions={parseTracks()}
              setSelection={setTextTracks}
              selectedItem={selectedTextTrack}
              copy={copy}
            />
          </MenuContainer>
        )}
        {qualityMenuOpen && (
          <MenuContainer isOpen={qualityMenuOpen} {...menuContainerStyleProps}>
            <VideoMenu
              menuLabel={videoText[copy].qualityDialogue}
              menuOptions={parseVideoQuality()}
              setSelection={setVideoQuality}
              selectedItem={videoQuality}
              copy={copy}
            />
          </MenuContainer>
        )}
      </StyledControlBar>
    </ControlBarContainer>
  )
}

ControlBar.propTypes = {
  ...selectedSystemPropTypes,
  videoPlayer: PropTypes.object.isRequired,
  videoPlayerContainer: PropTypes.object.isRequired,
  sources: PropTypes.array.isRequired,
  tracks: PropTypes.array,
  videoPlaying: PropTypes.bool.isRequired,
  videoUnplayed: PropTypes.bool.isRequired,
  videoBufferEnd: PropTypes.number.isRequired,
  isHidden: PropTypes.bool,
  videoLength: PropTypes.number.isRequired,
  videoCurrentTime: PropTypes.number.isRequired,
  videoCurrentVolume: PropTypes.number.isRequired,
  videoIsMuted: PropTypes.bool.isRequired,
  setVolume: PropTypes.func.isRequired,
  isMobile: PropTypes.bool.isRequired,
  tracksAvailable: PropTypes.bool.isRequired,
  togglePlayPause: PropTypes.func.isRequired,
  setSeek: PropTypes.func.isRequired,
  toggleMute: PropTypes.func.isRequired,
  toggleFullscreen: PropTypes.func.isRequired,
  videoIsFullscreen: PropTypes.bool.isRequired,
  setTextTracks: PropTypes.func.isRequired,
  selectedTextTrack: PropTypes.number.isRequired,
  resetInactivityTimer: PropTypes.func.isRequired,
  videoQuality: PropTypes.number.isRequired,
  setVideoQuality: PropTypes.func.isRequired,
  captionsMenuOpen: PropTypes.bool.isRequired,
  setCaptionsMenuOpen: PropTypes.func.isRequired,
  qualityMenuOpen: PropTypes.bool.isRequired,
  setQualityMenuOpen: PropTypes.func.isRequired,
  clearInactivityTimer: PropTypes.func.isRequired,
  copy: PropTypes.oneOf(['en', 'fr']).isRequired,
  compactModeThreshold: PropTypes.number.isRequired,
  videoPlayerWidth: PropTypes.number.isRequired
}

export default ControlBar
