import React, {useState} from 'react'
import PropTypes from 'prop-types'
import LogRocket from 'logrocket'
import {CardElement} from 'react-stripe-elements'
import PaymentClient from 'common-fe/clients/payment'
import {useStripe} from 'global/hooks/stripe'

import Button from 'react-uikit/button'
import {Grid} from 'react-uikit/layout'
import Loader from 'react-uikit/loader'

import styles from './styles.scss'
import BEMModule from 'utils/bem'
const bem = new BEMModule(styles)

const stripeStyles = {
    base: {
        fontFamily: 'museo-sans, Helvetica Neue, Helvetica, Arial, sans-serif',
        fontSize: '16px',
        color: '#999',
        padding: '200px 0',
        '::placeholder': {
            color: '#ccc',
        },
    },
    invalid: {
        color: '#fdbf56',
    },
}

const CardUpdate = ({onSubmit, showToast, user}) => {
    const [errorMessage, setErrorMessage] = useState('')
    const [isComplete, setIsComplete] = useState(false)
    const [isFocused, setIsFocused] = useState(false)
    const [isLoading, setIsLoading] = useState(false)
    const stripe = useStripe()

    const handleChange = ({complete, error: {message = ''} = {}}) => {
        setIsComplete(complete)
        setErrorMessage(message)
    }

    const handleClick = () => {
        setIsLoading(true)
        LogRocket.track('Payments - Card Update')
        setErrorMessage('')

        stripe
            ?.createToken()
            .then((res) =>
                PaymentClient.updatePaymentMethod({
                    token: res.token.id,
                    userId: user.id,
                }).then(() => {
                    onSubmit?.()
                    showToast?.()
                })
            )
            .catch(({errors} = {}) => {
                setIsLoading(false)

                if (errors?.length) {
                    setErrorMessage(errors[0].reason)
                } else {
                    setErrorMessage(
                        'Your card could not be processed at this time. Please try again later.'
                    )
                }
            })
    }

    const handleFocus = (focus) => setIsFocused(focus)

    const classNames = bem.classNames('c-card-update')
    const buttonClassNames = bem.classNames('c-card-update__button', {
        'is-loading': isLoading,
    })
    const buttonLabelClassNames = bem.classNames('c-card-update__button-label')
    const labelClassNames = bem.classNames('c-card-update__label')
    const loaderClassNames = bem.classNames('c-card-update__loader')
    const messageClassNames = bem.classNames('c-card-update__message')
    const inputClassNames = bem.classNames('c-card-update__input', {
        focus: isFocused,
        invalid: Boolean(errorMessage),
    })

    const cardInputId = 'card-input'

    return (
        <React.Fragment>
            <Grid className={classNames} gap={16} templateColumns="1fr">
                <p>The card you enter below will replace your existing card.</p>

                <form>
                    <label className={labelClassNames} htmlFor={cardInputId}>
                        Card Details
                    </label>

                    <CardElement
                        autofocus
                        className={inputClassNames}
                        id={cardInputId}
                        style={stripeStyles}
                        onBlur={() => handleFocus(false)}
                        onChange={handleChange}
                        onFocus={() => handleFocus(true)}
                    />
                </form>

                <div className={messageClassNames}>{errorMessage}</div>
            </Grid>

            <Button
                className={buttonClassNames}
                disabled={!isComplete && !errorMessage}
                variant="primary"
                onClick={handleClick}
            >
                <span className={buttonLabelClassNames}>
                    Update
                    {isLoading && (
                        <Loader
                            className={loaderClassNames}
                            color="white"
                            size="x-small"
                        />
                    )}
                </span>
            </Button>
        </React.Fragment>
    )
}

CardUpdate.propTypes = {
    showToast: PropTypes.func,
    user: PropTypes.object,
    onSubmit: PropTypes.func,
}

export default CardUpdate
