'use client'

import { cx, VariantProps } from 'class-variance-authority'
import { useRef, useState, VideoHTMLAttributes } from 'react'

import { Lang, languages } from '@scandic-hotels/common/constants/language'
import { FocalPoint } from '@scandic-hotels/common/utils/imageVault'
import { useIntl } from 'react-intl'
import { VideoPlayerButton } from './Button'
import { variants } from './variants'
import styles from './videoPlayer.module.css'

interface Caption {
  src: string
  srcLang: Lang
  isDefault: boolean
}

interface VideoPlayerProps extends VariantProps<typeof variants> {
  src: string
  className?: string
  captions?: Caption[]
  focalPoint?: FocalPoint
  autoPlay?: boolean
}

export function VideoPlayer({
  src,
  captions,
  focalPoint = { x: 50, y: 50 },
  className,
  variant = 'inline',
  autoPlay,
}: VideoPlayerProps) {
  const intl = useIntl()
  const videoRef = useRef<HTMLVideoElement>(null)
  const [isActivated, setIsActivated] = useState(
    (variant === 'hero' && (autoPlay ?? true)) || !!autoPlay
  )
  const [isPlaying, setIsPlaying] = useState(autoPlay ?? false)
  const [isMuted, setIsMuted] = useState(true)
  const defaultProps = getVideoPropsByVariant(variant, isActivated, autoPlay)

  const classNames = variants({
    className,
    variant,
  })

  function togglePlay() {
    const videoElement = videoRef.current
    if (videoElement) {
      if (variant === 'hero') {
        if (videoElement.paused) {
          videoElement.play()
        } else {
          videoElement.pause()
        }
      } else {
        setIsActivated(true)
        videoElement.play()
      }
    }
  }

  function handleMuteToggle() {
    const videoElement = videoRef.current
    if (videoElement) {
      const currentlyMuted = videoElement.muted
      videoElement.muted = !currentlyMuted
      setIsMuted(!currentlyMuted)
    }
  }

  function handleVolumeChangeEvent(event: React.UIEvent<HTMLVideoElement>) {
    if (event.currentTarget.muted && !isMuted) {
      setIsMuted(true)
    } else if (!event.currentTarget.muted && isMuted) {
      setIsMuted(false)
    }
  }

  const showPlayButton =
    variant === 'hero' || (variant === 'inline' && !isActivated)
  const showMuteButton = variant === 'inline' && isActivated

  return (
    <div className={cx(classNames, { [styles.isActivated]: isActivated })}>
      <video
        ref={videoRef}
        className={styles.video}
        src={src}
        style={
          focalPoint
            ? { objectPosition: `${focalPoint.x}% ${focalPoint.y}%` }
            : undefined
        }
        onPlay={() => setIsPlaying(true)}
        onPause={() => setIsPlaying(false)}
        onVolumeChange={handleVolumeChangeEvent}
        {...defaultProps}
      >
        {captions?.length
          ? captions.map(({ src, srcLang, isDefault }) => (
              <track
                key={src}
                src={src}
                kind="captions"
                srcLang={srcLang}
                label={languages[srcLang] || srcLang}
                default={isDefault}
              />
            ))
          : null}
      </video>
      {showPlayButton ? (
        <VideoPlayerButton
          className={styles.playButton}
          onPress={togglePlay}
          iconName={isPlaying ? 'pause' : 'play_arrow'}
          ariaLabel={
            isPlaying
              ? intl.formatMessage({
                  id: 'videoPlayer.pause',
                  defaultMessage: 'Pause video',
                })
              : intl.formatMessage({
                  id: 'videoPlayer.play',
                  defaultMessage: 'Play video',
                })
          }
        />
      ) : null}
      {showMuteButton ? (
        <VideoPlayerButton
          className={styles.muteButton}
          onPress={handleMuteToggle}
          iconName={isMuted ? 'volume_off' : 'volume_up'}
          ariaLabel={
            isMuted
              ? intl.formatMessage({
                  id: 'videoPlayer.mute',
                  defaultMessage: 'Mute video',
                })
              : intl.formatMessage({
                  id: 'videoPlayer.unmute',
                  defaultMessage: 'Unmute video',
                })
          }
        />
      ) : null}
    </div>
  )
}

function getVideoPropsByVariant(
  variant: VideoPlayerProps['variant'],
  isActive: boolean,
  autoPlay?: boolean
): VideoHTMLAttributes<HTMLVideoElement> {
  switch (variant) {
    case 'hero':
      return {
        controls: false,
        controlsList: 'nodownload nofullscreen noremoteplayback',
        autoPlay: autoPlay ?? true,
        muted: true,
        loop: true,
      }
    case 'inline':
    default:
      return {
        controls: isActive,
        controlsList: 'nodownload noremoteplayback',
        autoPlay: autoPlay ?? isActive,
        muted: true,
        loop: false,
      }
  }
}
