import React, {forwardRef, useImperativeHandle, useRef} from 'react'
import PropTypes from 'prop-types'
import {Elements, CardElement, injectStripe} from 'react-stripe-elements'
import {renderRealMoney} from 'common-fe/utils/render'
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',
    },
}

class _CardForm extends React.Component {
    state = {
        isComplete: false,
        isFocused: false,
        errorMessage: '',
    }

    handleBlur = () => this.setState({isFocused: false})

    handleChange = ({complete, error: {message = ''} = {}}) => {
        this.setState({
            isComplete: complete,
            errorMessage: message,
        })

        this.props.onChange?.({isComplete: complete})
    }

    handleFocus = () => this.setState({isFocused: true})

    getPaymentToken = () => {
        return this.props.stripe?.createToken().then((res) => res)
    }

    render() {
        const {errorMessage, isFocused} = this.state
        const {message} = this.props.error
        const cardInputClasses = bem.classNames(
            'c-payment-checkout__card-input',
            {
                focus: isFocused,
                invalid: errorMessage,
            }
        )
        const errorMessageClasses = bem.classNames(
            'c-payment-checkout__error-message'
        )
        const labelClasses = bem.classNames('c-payment-checkout__label')
        const cardInputId = 'card-input'

        return (
            <React.Fragment>
                <label className={labelClasses} htmlFor={cardInputId}>
                    Credit Card
                </label>
                <CardElement
                    id={cardInputId}
                    className={cardInputClasses}
                    style={stripeStyles}
                    onBlur={this.handleBlur}
                    onChange={this.handleChange}
                    onFocus={this.handleFocus}
                />
                <div className={errorMessageClasses} role="alert">
                    {errorMessage}
                </div>
                <div
                    className={errorMessageClasses}
                    role="alert"
                    style={{marginTop: 0}}
                >
                    {message}
                </div>
            </React.Fragment>
        )
    }
}

_CardForm.propTypes = {
    error: PropTypes.object,
    stripe: PropTypes.object,
    onChange: PropTypes.func,
}

const CardForm = injectStripe(_CardForm, {withRef: true})

const PaymentCheckout = forwardRef(
    ({course: {name}, error, order: {amount}, onChange}, ref) => {
        const paymentFormRef = useRef()

        useImperativeHandle(ref, () => ({
            getPaymentToken: () =>
                paymentFormRef.current.getWrappedInstance().getPaymentToken(),
        }))

        const horizontalLineClasses = bem.classNames(
            'c-payment-checkout__horizontal-line'
        )
        const itemDescriptionClasses = bem.classNames(
            'c-payment-checkout__item-description'
        )
        const itemValueClasses = bem.classNames(
            'c-payment-checkout__item-value'
        )
        const tableHeadingClasses = bem.classNames(
            'c-payment-checkout__table-heading'
        )

        return (
            <React.Fragment>
                <p className={tableHeadingClasses}>
                    <span>Portfolio</span>
                    <span>Total</span>
                </p>
                <hr className={horizontalLineClasses} />
                <p className={itemDescriptionClasses}>
                    <span>{name}</span>
                    <span className={itemValueClasses}>
                        {renderRealMoney(amount)}
                    </span>
                </p>
                <div style={{gridColumn: '1/-1'}}>
                    <Elements>
                        <CardForm
                            ref={paymentFormRef}
                            error={error}
                            onChange={onChange}
                        />
                    </Elements>
                </div>
            </React.Fragment>
        )
    }
)

PaymentCheckout.displayName = 'PaymentCheckout'

PaymentCheckout.propTypes = {
    course: PropTypes.shape({
        name: PropTypes.name,
    }),
    error: PropTypes.object,
    order: PropTypes.shape({
        amount: PropTypes.number,
    }),
    stripe: PropTypes.object,
    onChange: PropTypes.func,
}

export default PaymentCheckout
