import React from 'react'
import { View } from 'react-native'

import { StackWrapBox } from './StackWrapBox'
import { a11yProps } from '../utils/props/a11yProps'
import { getA11yPropsFromHtmlTag } from '../utils/a11y/semantics'
import { selectSystemProps } from '../utils/props/selectSystemProps'
import { useMediaQuerySpacing } from '../utils/useMediaQuerySpacing'
import { useSpacingScale } from '../utils/useSpacingScale'
import { useResponsiveProp } from '../utils/useResponsiveProp'
import { viewProps } from '../utils/props/viewProps'
import {
  StyleSheet as StyleSheetUtils,
  createMediaQueryStyles
} from '../utils/ssr-media-query/ssr-media-query'
import { useTheme } from '../ThemeProvider/useTheme'
import { useThemeTokens } from '../ThemeProvider/useThemeTokens'
import { useViewport } from '../ViewportProvider/useViewport'
import { getStackedContent } from './getStackedContent'
import { staticStyles, selectFlexStyles } from './common'

const [selectProps] = selectSystemProps([a11yProps, viewProps])

/**
 * The primary implementation of StackWrap.
 *
 * This is not intended to be used directly. It will automatically be used instead of StackWrap if:
 *
 * - On web, and,
 * - On a browser that supports CSS `gap` (most browser versions from 2020 onwards), and,
 * - The `space` between items is the same as the `gap` between wrapped rows (this is the
 *   default if `gap` prop is undefined)
 */
export const StackWrapGap = React.forwardRef(
  (
    {
      space = 1,
      tokens,
      variant,
      direction: directionProp = 'row',
      children,
      tag,
      accessibilityRole,
      itemAccessibilityRole,
      dataSet,
      ...rest
    },
    ref
  ) => {
    const viewport = useViewport()
    const {
      themeOptions: { enableMediaQueryStyleSheet }
    } = useTheme()
    const direction = useResponsiveProp(directionProp, 'row')
    const themeTokens = useThemeTokens('StackView', tokens, variant, { viewport })
    const flexStyles = selectFlexStyles(themeTokens)
    const selectedProps = selectProps({
      accessibilityRole,
      ...getA11yPropsFromHtmlTag(tag, accessibilityRole),
      ...rest
    })

    const { sizeByViewport } = useMediaQuerySpacing(space)
    const size = useSpacingScale(space)
    const gapStyle = { gap: size }

    const content = getStackedContent(children, { direction, space: 0, itemAccessibilityRole })

    const baseStyles = [flexStyles, staticStyles.wrap, staticStyles[direction]]

    let wrapStyles = [...baseStyles, gapStyle]
    let dataSetValue = dataSet

    if (enableMediaQueryStyleSheet) {
      const mediaQueryStyles = createMediaQueryStyles({
        xs: { gap: sizeByViewport.xs },
        sm: { gap: sizeByViewport.sm },
        md: { gap: sizeByViewport.md },
        lg: { gap: sizeByViewport.lg },
        xl: { gap: sizeByViewport.xl }
      })

      const { ids, styles } = StyleSheetUtils.create({
        stackWrap: {
          ...mediaQueryStyles
        }
      })

      wrapStyles = [...baseStyles, styles.stackWrap]
      dataSetValue = { media: ids.stackWrap, ...dataSet }
    }

    return (
      <View ref={ref} {...selectedProps} style={wrapStyles} dataSet={dataSetValue}>
        {content}
      </View>
    )
  }
)
StackWrapGap.displayName = 'StackWrapGap'

StackWrapGap.propTypes = StackWrapBox.propTypes
