import React from 'react'
import {
  StyleSheet,
  ActivityIndicator,
  TouchableOpacity,
  Text,
  View,
} from 'react-native'
import { borderRadius, colors, fonts, spacing, system } from '../theme'
import { MaterialIcons } from '@expo/vector-icons'

// The complete reusable Button component
// The props are passed from the parent component
// The props are destructured to get the values
// Those are the props that are passed from the parent component
// eg. onPress, title, color, disabled, style, textStyle, children, size, type, variant, etc
const Button = ({
  onPress,
  leftIcon,
  rightIcon,
  loading,

  color,
  disabled,
  style,
  textStyle,
  children,
  size,
  type,
  variant,
  fullWidth,

  mx = 0,
  my = spacing.s_2,
  mt = 0,
  mb = 0,
  ml = 0,
  mr = 0,

  ...props
}) => {
  // The type of button is defined here
  // The type can be one of the following
  // 'filled', 'outlined', 'text', 'link'
  // The default type is 'solid'
  const buttonType = type || 'filled'

  // The variant of the button is defined here
  // The variant can be one of the following
  //  'primary',  'success', 'warning', 'danger', 'info', 'light', 'dark'
  // The default variant is 'default'
  const buttonVariant = variant || 'primary'

  // The size of the button is defined here
  // The size can be one of the following
  // 'xs', 'sm', 'md', 'lg', 'xl'
  // The default size is 'md'
  const buttonSize = size || 'md'

  // The color of the button is defined here
  // The color is the background color of the button
  const buttonColor = color
  // The disabled state of the button is defined here
  // The disabled state can be one of the following
  // true, false
  // The default disabled state is false
  const buttonDisabled = disabled || false

  // The onPress function is defined here
  // The onPress function can be one of the following
  // function, undefined
  // The default onPress function is undefined
  const buttonOnPress = onPress || undefined

  // The title of the button is defined here
  // The title can be one of the following
  // string, undefined
  // The default title is undefined
  const buttonTitle = children || undefined

  // The style of the button is defined here
  // The style can be one of the following
  // object, undefined
  // The default style is undefined
  const buttonStyle = style || undefined

  // The textStyle of the button is defined here
  // The textStyle can be one of the following
  // object, undefined
  // The default textStyle is undefined
  const buttonTextStyle = textStyle || undefined

  // The leftIcon of the button is defined here
  // The leftIcon can be one of the following
  // object, undefined
  // The default leftIcon is undefined
  const buttonLeftIcon = leftIcon || undefined

  // The rightIcon of the button is defined here
  // The rightIcon can be one of the following
  // object, undefined
  // The default rightIcon is undefined
  const buttonRightIcon = rightIcon || undefined

  // The loading state of the button is defined here
  // The loading state can be one of the following
  // true, false
  // The default loading state is false
  const buttonLoading = loading || false

  // margin styles
  const marginStyles = {
    marginHorizontal: mx,
    marginVertical: my,
    marginTop: mt,
    marginBottom: mb,
    marginLeft: ml,
    marginRight: mr,
  }

  // The button is returned here
  return (
    <TouchableOpacity
      onPress={buttonOnPress}
      disabled={buttonDisabled}
      activeOpacity={0.8}
      style={[
        styles.buttonStyle,

        // The size of button is defined here
        buttonSize === 'xs' && styles.buttonSizeXs,
        buttonSize === 'sm' && styles.buttonSizeSm,
        buttonSize === 'md' && styles.buttonSizeMd,
        buttonSize === 'lg' && styles.buttonSizeLg,
        buttonSize === 'xl' && styles.buttonSizeXl,

        // The variant of button is defined here
        buttonVariant === 'default' && styles.buttonVariantDefault,
        buttonVariant === 'primary' && styles.buttonVariantPrimary,
        buttonVariant === 'success' && styles.buttonVariantSuccess,
        buttonVariant === 'warning' && styles.buttonVariantWarning,
        buttonVariant === 'danger' && styles.buttonVariantDanger,
        buttonVariant === 'info' && styles.buttonVariantInfo,
        buttonVariant === 'light' && styles.buttonVariantLight,
        buttonVariant === 'dark' && styles.buttonVariantDark,

        fullWidth == true || fullWidth == undefined ? styles.fullWidth : '',

        // The color of button is defined here

        // The type of button is defined here
        buttonType === 'filled' && styles.buttonSolid,
        buttonType === 'outlined' && styles.buttonOutline,
        buttonType === 'text' && styles.buttonClear,
        buttonType === 'link' && styles.buttonLink,

        buttonColor && { backgroundColor: buttonColor.background },
        // The disabled state of button is defined here
        buttonDisabled && styles.buttonDisabled,
        marginStyles,
        buttonStyle,
        system.UIType == 'rounded' && styles.buttonRounded,
      ]}
      {...props}
    >
      {buttonLoading ? (
        <ActivityIndicator style={styles.loadingStyle} color={colors.white} />
      ) : (
        <>
          {buttonLeftIcon && (
            <View
              style={[
                styles.leftIconStyle,
                buttonSize === 'sm' && styles.iconSizeSm,
                buttonSize === 'md' && styles.iconSizeMd,
                buttonSize === 'lg' && styles.iconSizeLg,
              ]}
            >
              <MaterialIcons
                name={buttonLeftIcon}
                style={[
                  buttonSize === 'sm' && styles.iconSizeSm,

                  buttonSize === 'md' && styles.iconSizeMd,
                  buttonSize === 'lg' && styles.iconSizeLg,

                  buttonColor && { color: buttonColor.text },

                  buttonType === 'filled' && styles.textSolid,
                  buttonType === 'outlined' && styles.textOutline,
                  buttonType === 'text' && styles.textClear,
                  buttonType === 'link' && styles.textLink,
                ]}
              />
            </View>
          )}
        </>
      )}
      <Text
        style={[
          styles.textStyle,
          buttonTextStyle,

          // The size of button is defined here
          buttonSize === 'sm' && styles.textSizeSm,
          buttonSize === 'md' && styles.textSizeMd,
          buttonSize === 'lg' && styles.textSizeLg,

          // The variant of button is defined here
          buttonVariant === 'default' && styles.textVariantDefault,
          buttonVariant === 'primary' && styles.textVariantPrimary,
          buttonVariant === 'success' && styles.textVariantSuccess,
          buttonVariant === 'warning' && styles.textVariantWarning,
          buttonVariant === 'danger' && styles.textVariantDanger,
          buttonVariant === 'info' && styles.textVariantInfo,
          buttonVariant === 'light' && styles.textVariantLight,
          buttonVariant === 'dark' && styles.textVariantDark,

          // The color of button is defined here
          buttonColor && { color: buttonColor.text },

          // The type of button is defined here
          buttonType === 'filled' && styles.textSolid,
          buttonType === 'outlined' && styles.textOutline,
          buttonType === 'text' && styles.textClear,
          buttonType === 'link' && styles.textLink,
        ]}
      >
        {!loading && buttonTitle}
      </Text>
      {buttonRightIcon && (
        <View
          style={[
            styles.rightIconStyle,
            buttonSize === 'sm' && styles.iconSizeSm,
            buttonSize === 'md' && styles.iconSizeMd,
            buttonSize === 'lg' && styles.iconSizeLg,
          ]}
        >
          <MaterialIcons
            name={buttonRightIcon}
            style={[
              buttonSize === 'sm' && styles.iconSizeSm,
              buttonSize === 'md' && styles.iconSizeMd,
              buttonSize === 'lg' && styles.iconSizeLg,

              buttonColor && { color: buttonColor.text },

              buttonType === 'filled' && styles.textSolid,
              buttonType === 'outlined' && styles.textOutline,
              buttonType === 'text' && styles.textClear,
              buttonType === 'link' && styles.textLink,
            ]}
          />
        </View>
      )}
    </TouchableOpacity>
  )
}

// The styles are defined here
const styles = StyleSheet.create({
  buttonStyle: {
    backgroundColor: colors.primary,
    borderRadius: borderRadius.br_1,
    paddingVertical: spacing.s_3,
    paddingHorizontal: borderRadius.br_3,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
  },
  textStyle: {
    color: colors.white,
    fontWeight: 'bold',
    // textTransform: 'uppercase',
    fontSize: fonts.body,
    textAlign: 'center',
  },

  fullWidth: {
    width: '100%',
  },

  loadingStyle: {
    position: 'absolute',
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
    alignItems: 'center',
    justifyContent: 'center',
  },

  leftIconStyle: {
    marginRight: spacing.s_2,
  },

  rightIconStyle: {
    marginLeft: spacing.s_2,
  },

  buttonDisabled: {
    opacity: 0.5,
  },

  buttonRounded: {
    borderRadius: borderRadius.br_100,
  },
  // icon styles with different sizes
  iconSizeSm: {
    fontSize: fonts.body,
  },
  iconSizeMd: {
    fontSize: fonts.h4,
  },
  iconSizeLg: {
    fontSize: fonts.h3,
  },

  // The button types are defined here

  // container
  buttonSolid: {
    backgroundColor: colors.primary,
  },
  buttonOutline: {
    backgroundColor: 'transparent',
    borderWidth: 1,
    borderColor: colors.primary,
  },
  buttonClear: {
    backgroundColor: 'transparent',
  },
  buttonLink: {
    backgroundColor: 'transparent',
  },

  // text
  textSolid: {
    color: colors.white,
  },
  textOutline: {
    color: colors.primary,
  },
  textClear: {
    color: colors.primary,
  },
  textLink: {
    color: colors.primary,
  },

  // The button sizes are defined here

  // container
  buttonSizeSm: {
    paddingVertical: spacing.s_1,
    paddingHorizontal: spacing.s_2,
  },
  buttonSizeMd: {
    paddingVertical: spacing.s_3,
    paddingHorizontal: spacing.s_3,
  },
  buttonSizeLg: {
    paddingVertical: spacing.s_4,
    paddingHorizontal: spacing.s_4,
  },

  // text
  textSizeSm: {
    fontSize: fonts.caption,
  },
  textSizeMd: {
    fontSize: fonts.body,
  },
  textSizeLg: {
    fontSize: fonts.h3,
  },

  // The button variants are defined here

  // container
  buttonVariantDefault: {
    backgroundColor: colors.primary,
  },
  buttonVariantPrimary: {
    backgroundColor: colors.primary,
  },

  buttonVariantSuccess: {
    backgroundColor: colors.success,
  },
  buttonVariantWarning: {
    backgroundColor: colors.warning,
  },
  buttonVariantDanger: {
    backgroundColor: colors.error,
  },
  buttonVariantInfo: {
    backgroundColor: colors.info,
  },
  buttonVariantLight: {
    backgroundColor: colors.light,
  },
  buttonVariantDark: {
    backgroundColor: colors.dark,
  },

  // text
  textVariantDefault: {
    color: colors.white,
  },
  textVariantPrimary: {
    color: colors.white,
  },
  textVariantSecondary: {
    color: colors.white,
  },
  textVariantSuccess: {
    color: colors.white,
  },
  textVariantWarning: {
    color: colors.white,
  },
  textVariantDanger: {
    color: colors.white,
  },
  textVariantInfo: {
    color: colors.white,
  },
  textVariantLight: {
    color: colors.textDark,
  },
  textVariantDark: {
    color: colors.white,
  },
})
// The Button component is exported here
export default Button
