import React from 'react'
import PropTypes from 'prop-types'
import { Pressable, Platform, StyleSheet } from 'react-native'
import { a11yProps } from '../utils/props/a11yProps'
import { linkProps } from '../utils/props/linkProps'
import { hrefAttrsProp } from '../utils/props/hrefAttrsProp'
import { viewProps } from '../utils/props/viewProps'
import { getTokensPropType } from '../utils/props/tokens'
import { resolvePressableTokens } from '../utils/pressability'
import { variantProp } from '../utils/props/variantProp'
import { copyPropTypes } from '../utils/props/copyPropTypes'
import { selectSystemProps } from '../utils/props/selectSystemProps'
import { useCopy } from '../utils/useCopy'
import { useThemeTokensCallback } from '../ThemeProvider/useThemeTokens'
import { dictionary as defaultDictionary } from './dictionary'

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

const selectOuterStyles = ({ borderColor, borderWidth, borderGap, borderRadius, padding }) => ({
  outline: 'none',
  borderColor,
  borderWidth,
  borderGap,
  borderRadius,
  padding
})

export const DownloadApp = React.forwardRef(
  (
    {
      copy = 'en',
      dictionary = defaultDictionary,
      type = 'ios',
      href,
      onPress,
      tokens = {},
      variant = {},
      ...props
    },
    ref
  ) => {
    const getCopy = useCopy({ dictionary, copy })
    const { hrefAttrs, rest } = hrefAttrsProp.bundle(props)

    const selectedProps = selectProps({
      accessibilityRole: href ? 'link' : 'button',
      href,
      onPress: linkProps.handleHref({ href, onPress }),
      hrefAttrs,
      ...rest
    })

    const getDownloadAppTokens = useThemeTokensCallback('DownloadApp', tokens, variant)
    const resolveDownloadAppTokens = (pressableState) => {
      const themeTokens = resolvePressableTokens(getDownloadAppTokens, pressableState, {})
      return selectOuterStyles(themeTokens)
    }

    const { androidENIcon, androidFRIcon, iosENIcon, iosFRIcon } = getDownloadAppTokens()

    const imageResources = {
      en: {
        android: androidENIcon,
        ios: iosENIcon
      },
      fr: {
        android: androidFRIcon,
        ios: iosFRIcon
      }
    }
    const IconComponent = imageResources[copy][type]

    return (
      <Pressable
        ref={ref}
        style={(pressState) => [resolveDownloadAppTokens(pressState), staticStyles.row]}
        {...selectedProps}
      >
        <IconComponent
          style={staticImageSizes[type][copy]}
          alt={type === 'ios' ? getCopy('altTextIos') : getCopy('altTextAndroid')}
        />
      </Pressable>
    )
  }
)
DownloadApp.displayName = 'DownloadApp'

const dictionaryContentShape = PropTypes.shape({
  altTextAndroid: PropTypes.string.isRequired,
  altTextIos: PropTypes.string.isRequired
})

DownloadApp.propTypes = {
  ...selectedSystemPropTypes,
  /**
   * Whether the English or French copy will be used (e.g. for accessibility labels).
   */
  copy: copyPropTypes,
  /**
   * Override the default dictionary, by passing the complete dictionary object for `en` and `fr`
   */
  dictionary: PropTypes.shape({
    en: dictionaryContentShape,
    fr: dictionaryContentShape
  }),
  /**
   * Select the type of image to show.
   */
  type: PropTypes.oneOf(['android', 'ios']),
  /**
   * It's a simple link that opens the Download Button instead of the onPress function.
   */
  href: PropTypes.string,
  /**
   * Function called when the button is pressed. Required unless the button has a href.
   */
  onPress: PropTypes.func,
  /**
   * DownloadApp tokens.
   */
  tokens: getTokensPropType('DownloadApp'),
  /**
   * DownloadApp variant.
   */
  variant: variantProp.propType
}

const staticStyles = StyleSheet.create({
  row: {
    ...Platform.select({
      web: {
        display: 'inline-flex',
        width: 'fit-content'
      },
      default: {
        alignSelf: 'flex-start'
      }
    })
  }
})

const staticImageSizes = {
  android: {
    en: {
      width: 162,
      height: 48
    },
    fr: {
      width: 162,
      height: 48
    }
  },
  ios: {
    en: {
      width: 144,
      height: 48
    },
    fr: {
      width: 152,
      height: 48
    }
  }
}
