import React from 'react'
import { Pressable, StyleSheet } from 'react-native-web'
import PropTypes from 'prop-types'
import { viewports } from '@telus-uds/system-constants'
import {
  StackView,
  Typography,
  useViewport,
  horizontalScrollUtils,
  useThemeTokensCallback
} from '@telus-uds/components-base'
import styled from 'styled-components'
import { getTimestamp } from '../shared/VideoSplash/helpers'
import { VideoPropType, RefPropType } from './videoPropType'
import VideoSplash from '../shared/VideoSplash/VideoSplash'

const { getItemPositionLayoutHandler, itemPositionsPropType } = horizontalScrollUtils

// Use a React Native (web) outer container so it can take an onLayout callback, to
// access position in VideoSlider's UDS HorizontalScroll and update its itemPositions
const createReactNativeStyles = ({
  pressablePaddingBottom,
  pressablePaddingVertical,
  pressablePaddingHorizontal,
  pressableBorderTopWidth,
  pressableBorderTopColor
}) =>
  StyleSheet.create({
    container: {
      cursor: 'pointer'
    },
    horizontal: {
      paddingBottom: pressablePaddingBottom
    },
    framed: {
      paddingVertical: pressablePaddingVertical,
      paddingHorizontal: pressablePaddingHorizontal
    },
    framedLine: {
      borderTopWidth: pressableBorderTopWidth,
      borderTopColor: pressableBorderTopColor
    }
  })

const ImageContainer = styled.div`
  padding: ${(props) => `${props.outerBorderGap}px`};
  border: ${(props) => `${props.outerBorderWidth}px solid ${props.outerBorderColor}`};
  border-radius: ${({ outerBorderRadius }) => outerBorderRadius}px;
`

const VideoThumbnail = styled.div`
  position: relative;
  width: ${(props) => (props.layout === 'vertical' ? '100%' : '144px')};
  flex-shrink: 0;

  * button {
    display: none;
  }

  // use a pseudo-element to ensure aspect ratio
  &::before {
    content: '';
    display: block;
    padding-bottom: 56.25%;
  }

  &::after {
    content: '';
    border: ${({ borderWidth }) => borderWidth}px solid;
    border-color: ${({ borderColor }) => borderColor};
    border-radius: ${({ borderRadius }) => borderRadius}px;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
  }

  & > div {
    border-radius: ${({ borderRadius }) => borderRadius}px;
  }
`

const ThumbnailTitleContainer = styled.div`
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
`

const VideoPickerThumbnail = React.forwardRef(
  (
    {
      videoPlayerRef,
      selectedVideoId,
      video,
      onSelectVideo,
      layout = 'vertical',
      isFramed,
      itemPositions,
      index,
      width = '100%'
    },
    ref
  ) => {
    const viewport = useViewport()
    const getTokens = useThemeTokensCallback('VideoPickerThumbnail', {}, {})

    const { timestamp } = getTimestamp(video.videoLength, video.copy)
    const isPlaying = selectedVideoId === video.videoId

    const renderThumbnailImage = (themeTokens) => {
      return (
        <VideoThumbnail {...themeTokens} isPlaying={isPlaying} layout={layout}>
          <VideoSplash
            simpleMode
            poster={
              video.posterSrc || `https://img.youtube.com/vi/${video.videoId}/maxresdefault.jpg`
            }
            videoLength={video.videoLength}
            copy={video.copy}
          />
        </VideoThumbnail>
      )
    }

    const renderThumbnailInfo = ({ titleColor, subTitleColor }) => (
      <StackView space={2} tokens={{ flexShrink: 1 }}>
        <ThumbnailTitleContainer viewport={viewport}>
          <Typography variant={{ bold: true }} tokens={{ color: titleColor }}>
            {video.title}
          </Typography>
        </ThumbnailTitleContainer>
        {viewport !== viewports.xs && (
          <Typography variant={{ size: 'micro' }} tokens={{ color: subTitleColor }}>
            {timestamp}
          </Typography>
        )}
      </StackView>
    )

    const handleLayout =
      itemPositions !== undefined
        ? getItemPositionLayoutHandler(itemPositions.positions, index)
        : undefined

    const onKeyPress = (event) => {
      if (['Space', 'Enter'].includes(event.key)) {
        onSelectVideo(video)
        const splashButton = videoPlayerRef.current?.querySelector('button')
        if (splashButton) splashButton.focus()
      }
    }

    return (
      <Pressable
        key={video.videoId}
        onLayout={handleLayout}
        onPress={() => onSelectVideo(video)}
        testID={`thumbnail-container-${video.videoId}`}
        onKeyPress={onKeyPress}
        accessibilityRole="radio"
        accessibilityState={{ checked: isPlaying }}
        style={({ hovered: hover, focused: focus, pressed }) => {
          const themeTokens = getTokens({ hover, focus, pressed, selected: isPlaying })

          const rnStyles = createReactNativeStyles(themeTokens)
          return [
            rnStyles.container,
            layout === 'horizontal' && rnStyles.horizontal,
            isFramed && rnStyles.framed,
            isFramed && index > 0 && rnStyles.framedLine,
            { width },
            { outline: 'none' }
          ]
        }}
        ref={ref}
      >
        {({ hovered: hover, focused: focus, pressed }) => {
          const themeTokens = getTokens({ hover, focus, pressed, selected: isPlaying })

          return (
            <StackView
              space={layout === 'vertical' ? 2 : 3}
              direction={layout === 'vertical' ? 'column' : 'row'}
            >
              <ImageContainer {...themeTokens}>{renderThumbnailImage(themeTokens)}</ImageContainer>
              {renderThumbnailInfo(themeTokens)}
            </StackView>
          )
        }}
      </Pressable>
    )
  }
)

VideoPickerThumbnail.displayName = 'VideoPickerThumbnail'

VideoPickerThumbnail.propTypes = {
  selectedVideoId: PropTypes.string,
  onSelectVideo: PropTypes.func,
  video: VideoPropType,
  videoPlayerRef: RefPropType,
  layout: PropTypes.oneOf(['vertical', 'horizontal']),
  isFramed: PropTypes.bool,
  itemPositions: itemPositionsPropType,
  index: PropTypes.number,
  width: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
}

export default VideoPickerThumbnail
