import { CardNumberElement, CardCvcElement, CardExpiryElement } from '@stripe/react-stripe-js'
import { StripeCardElementOptions } from '@stripe/stripe-js'
import { Input, InputWrapperProps, Box, BoxProps, useMantineTheme, useComputedColorScheme } from '@tidbcloud/uikit'
import { FONT_FAMILY } from '@tidbcloud/uikit/theme'
import { getPrimaryShade } from '@tidbcloud/uikit/utils'

import { useStyles } from './CardElement.styles'

const useStripeElementOptions = () => {
  const theme = useMantineTheme()
  const { classes } = useStyles()
  const colorScheme = useComputedColorScheme()
  const primaryShade = getPrimaryShade(theme, colorScheme)

  // https://stripe.com/docs/js/elements_object/create_element?type=card#elements_create-options-classes
  const styles: StripeCardElementOptions = {
    classes: {
      base: classes.base,
      focus: classes.focus,
      invalid: classes.invalid
    },
    style: {
      base: {
        fontFamily: FONT_FAMILY,
        fontSmoothing: 'antialiased',
        fontSize: '14px',
        lineHeight: '38px',
        textTransform: 'capitalize',
        color: colorScheme === 'dark' ? theme.colors.carbon[8] : theme.black,
        '::placeholder': {
          // ...theme.fn.placeholderStyles()
        }
      },
      invalid: {
        iconColor: theme.colors.red[primaryShade],
        color: theme.colors.red[primaryShade]
      }
    }
  }

  return styles
}

export interface CardNumberInputProps extends Omit<InputWrapperProps, 'children'> {
  wrapper?: BoxProps
}

export const CardNumberInput: React.FC<React.PropsWithChildren<CardNumberInputProps>> = ({
  children,
  wrapper,
  ...rest
}) => {
  const basicOptions = useStripeElementOptions()
  return (
    <Input.Wrapper styles={{ label: { marginBottom: 8 } }} {...rest}>
      <Box {...wrapper}>
        <CardNumberElement options={{ ...basicOptions, showIcon: true }} />
      </Box>
    </Input.Wrapper>
  )
}

export interface CardCVCInputProps extends Omit<InputWrapperProps, 'children'> {
  wrapper?: BoxProps
}

export const CardCVCInput: React.FC<React.PropsWithChildren<CardCVCInputProps>> = ({ children, wrapper, ...rest }) => {
  const basicOptions = useStripeElementOptions()

  return (
    <Input.Wrapper styles={{ label: { marginBottom: 8 } }} {...rest}>
      <Box {...wrapper}>
        <CardCvcElement options={basicOptions} />
      </Box>
    </Input.Wrapper>
  )
}

export interface CardExpiryInputProps extends Omit<InputWrapperProps, 'children'> {
  wrapper?: BoxProps
}

export const CardExpiryInput: React.FC<React.PropsWithChildren<CardExpiryInputProps>> = ({
  children,
  wrapper,
  ...rest
}) => {
  const basicOptions = useStripeElementOptions()

  return (
    <Input.Wrapper styles={{ label: { marginBottom: 8 } }} {...rest}>
      <Box {...wrapper}>
        <CardExpiryElement options={basicOptions} />
      </Box>
    </Input.Wrapper>
  )
}
