import { Box, Button } from '@qonsoll/react-design'
import { Player, Recorder, VideoSnapshot } from '@qonsoll/qvideo'
import React, { Fragment, memo, useCallback, useMemo } from 'react'

import { Icon } from '@qonsoll/icons'
import PropTypes from 'prop-types'
import { useSize } from '@umijs/hooks'

const apiKey = process.env.REACT_APP_QVIDEO_API_KEY
const DEFAULT_ASPECT_RATIO = 16 / 9

/**
 * It's a component that renders either a video player or a video recorder depending on whether a video
 * has been uploaded or not
 * @param variant - The shape of the video player.
 * @param onUploadVideo - A callback function that is called when the video is uploaded.
 * @param videoToken - The video token of the video that is being played.
 * @param isViewer - boolean
 * @param className - string
 * @param userId - The userId of the user who is viewing the video.
 * @param spinnerSize - The size of the spinner.
 * @param playButtonSize - The size of the play button.
 * @param [isChapters=true] - Whether to show the chapters button.
 * @param [spinnerText=loading] - The text that appears in the spinner.
 * @param [videoDuration=30] - The duration of the video in seconds.
 * @param [isScreenRecord=true] - If true, the video will be recorded using the screen capture API.
 * @param [isNotes=true] - Whether to show the notes button.
 * @param [isCancel=true] - Whether or not to show the cancel button.
 * @param [isUpload=true] - If true, the user can upload a video.
 * @param [isLink=true] - If true, the video will be linked to the player.
 * @param rest - any
 * @returns A video player or a video recorder.
 */

const Video = (props) => {
  const {
    variant,
    onUploadVideo,
    videoToken,
    isViewer,
    className,
    autoHeight,
    aspectRatio = DEFAULT_ASPECT_RATIO,

    // Player
    userId,
    spinnerSize,
    playButtonSize,

    // Recorder
    isChapters = true,
    spinnerText = 'loading',
    videoDuration = 30,
    isScreenRecord = true,
    isNotes = true,
    isCancel = true,
    isUpload = true,
    isLink = true,

    width = '100%',
    height,

    ...rest
  } = props

  const [{ width: wrapperWidth }, ref] = useSize()

  const variantProps = useMemo(
    () => (variant === 'circle' ? { circle: true } : { variant }),
    [variant]
  )
  const isRemoveVisible = useMemo(() => onUploadVideo && !isViewer, [
    onUploadVideo,
    isViewer
  ])

  const handleRemove = useCallback(() => onUploadVideo(null), [onUploadVideo])

  const computedWidth = useMemo(() => width, [width])
  const computedHeight = useMemo(() => height || wrapperWidth / aspectRatio, [
    wrapperWidth,
    aspectRatio,
    height
  ])

  return (
    <Box
      ref={ref}
      {...rest}
      width={computedWidth}
      height={computedHeight}
      position="relative">
      {videoToken ? (
        <Fragment>
          {isRemoveVisible && (
            <Box
              top="8px"
              right="8px"
              position="absolute"
              inset="0px"
              zIndex={1}>
              <Button
                zIndex={400}
                danger
                type="primary"
                onClick={handleRemove}
                icon={<Icon name="TrashFilled" fill="white" size="20px" />}
              />
            </Box>
          )}
          <Player
            userId={userId}
            apiKey={apiKey}
            videoToken={videoToken}
            {...variantProps}
            spinnerSize={spinnerSize}
            playButtonSize={playButtonSize}
          />
        </Fragment>
      ) : isViewer ? (
        <VideoSnapshot error={{ text: 'Video not uploaded' }} />
      ) : (
        <Recorder
          {...variantProps}
          onUpload={onUploadVideo}
          apiKey={apiKey}
          autoStart
          isCameraConfig
          isMicroConfig
          isChapters={isChapters}
          spinnerText={spinnerText}
          videoDuration={videoDuration}
          isScreenRecord={isScreenRecord}
          isNotes={isNotes}
          isCancel={isCancel}
          isUpload={isUpload}
          isLink={isLink}
        />
      )}
    </Box>
  )
}

Video.propTypes = {
  className: PropTypes.string,
  isCancel: PropTypes.bool,
  isChapters: PropTypes.bool,
  isLink: PropTypes.bool,
  isNotes: PropTypes.bool,
  isScreenRecord: PropTypes.bool,
  isUpload: PropTypes.bool,
  isViewer: PropTypes.bool,
  onUploadVideo: PropTypes.func,
  playButtonSize: PropTypes.any,
  spinnerSize: PropTypes.any,
  spinnerText: PropTypes.string,
  userId: PropTypes.string,
  variant: PropTypes.string,
  videoDuration: PropTypes.number,
  videoToken: PropTypes.string
}

export default memo(Video)
