import React from 'react'
import PropTypes from 'prop-types'

import Form from 'react-toolkit/form'
import inputNames from 'common-fe/constants/input-names'
import investmentApproaches from 'common-fe/constants/investment-approaches'
import FormError from 'common-fe/utils/form-error'
import {sparsifyObj} from 'common-fe/utils'

import Button from 'react-uikit/button'
import InvestmentApproachInput from 'components/investment-approach-input'
import SelectInput from 'react-uikit/select-input'
import TextInput from 'react-uikit/input-text'
import TextArea from 'react-uikit/textarea'

import BEMModule from 'utils/bem'
import {renderLargeNumber} from 'common-fe/utils/render'
import styles from './styles.scss'
const bem = new BEMModule(styles)

import {
    PERSONAL_PORTFOLIO_FUNDING_AMOUNTS,
    PERSONAL_PORTFOLIO_FUNDING_AMOUNTS_PREMIUM,
    PORTFOLIO_NAME_MAX_LENGTH,
} from 'store/config'

class PortfolioCreationForm extends React.Component {
    static formName = 'portfolio-creation'

    static defaultState = {
        data: {
            [inputNames.NAME]: '',
            [inputNames.FUNDING_AMOUNT]: {
                label: renderLargeNumber(PERSONAL_PORTFOLIO_FUNDING_AMOUNTS[0]),
                value: PERSONAL_PORTFOLIO_FUNDING_AMOUNTS[0],
            },
            [inputNames.INVESTMENT_APPROACH]: 'NONE',
            [inputNames.DESCRIPTION]: '',
        },
        error: {},
    }

    form = React.createRef()

    get initialState() {
        return {
            data: {...PortfolioCreationForm.defaultState.data},
            error: {...PortfolioCreationForm.defaultState.error},
        }
    }

    get fundingOptions() {
        const {isPremiumUser} = this.props
        const fundingAmounts = isPremiumUser
            ? PERSONAL_PORTFOLIO_FUNDING_AMOUNTS_PREMIUM
            : PERSONAL_PORTFOLIO_FUNDING_AMOUNTS
        const options = fundingAmounts.map((amount) => ({
            label: renderLargeNumber(amount),
            value: amount,
        }))

        return options
    }

    change = ({name, value}) => {
        this.props.onChange && this.props.onChange({[name]: value})
    }

    createPortfolio = (data) => {
        const {createPortfolio, onError, onSubmit} = this.props

        if (!createPortfolio) {
            return
        }

        const payload = sparsifyObj({
            [inputNames.NAME]: data[inputNames.NAME],
            [inputNames.FUNDING_AMOUNT]: data[inputNames.FUNDING_AMOUNT].value,
            [inputNames.INVESTMENT_APPROACH]:
                investmentApproaches[data[inputNames.INVESTMENT_APPROACH]]
                    .value,
            [inputNames.DESCRIPTION]: data[inputNames.DESCRIPTION],
        })

        createPortfolio(payload, {redirect: true})
            .then(() => onSubmit && onSubmit(payload))
            .catch((err) => {
                if (!err.inlineErrors || !err.inlineErrors.length || !onError) {
                    return
                }

                const error = new FormError(
                    Object.keys(PortfolioCreationForm.defaultState.data),
                    err.inlineErrors
                )

                onError && onError(error)
            })
    }

    render() {
        const {data, error, validateOnUpdate, onError} = this.props

        const nameClassNames = bem.classNames('c-portfolio-creation__name')
        const nameInputClassNames = bem.classNames(
            'c-portfolio-creation__name-input'
        )
        const startingValueClassNames = bem.classNames(
            'c-portfolio-creation__starting-value'
        )
        const startingValueLabelClassNames = bem.classNames(
            'c-portfolio-creation__starting-value-label'
        )
        const descriptionClassNames = bem.classNames(
            'c-portfolio-creation__description'
        )
        const approachClassNames = bem.classNames(
            'c-portfolio-creation__approach'
        )
        const hrClassNames = bem.classNames('c-portfolio-creation__hr')
        const labelClassNames = bem.classNames('c-portfolio-creation__label')
        const createButtonClassName = bem.classNames(
            'c-portfolio-creation__button'
        )

        return (
            <Form
                data={data}
                error={error}
                name={PortfolioCreationForm.formName}
                submitOnEnter={false}
                validateOnUpdate={validateOnUpdate}
                onChange={this.change}
                onError={onError}
                onSubmit={this.createPortfolio}
            >
                <section className={nameClassNames}>
                    <label htmlFor={inputNames.NAME}>Portfolio Name</label>

                    <Form.Field
                        className={nameInputClassNames}
                        component={TextInput.Alternate}
                        maxLength={PORTFOLIO_NAME_MAX_LENGTH}
                        name={inputNames.NAME}
                        required
                    />
                </section>

                <section className={startingValueClassNames}>
                    <div className={startingValueLabelClassNames}>
                        <span>Starting Value</span>
                        <span>USD</span>
                    </div>
                    <div>
                        <Form.Field
                            component={SelectInput}
                            name={inputNames.FUNDING_AMOUNT}
                            options={this.fundingOptions}
                            required
                            size="small"
                        />
                    </div>
                </section>

                <hr className={hrClassNames} />

                <section className={approachClassNames}>
                    <div>
                        <label
                            className={labelClassNames}
                            htmlFor={inputNames.INVESTMENT_APPROACH}
                        >
                            Investment Approach
                        </label>
                        <Form.Field
                            component={InvestmentApproachInput}
                            name={inputNames.INVESTMENT_APPROACH}
                            required
                        />
                    </div>
                </section>
                <section className={descriptionClassNames}>
                    <label htmlFor={inputNames.DESCRIPTION}>Description</label>
                    <Form.Field
                        component={TextArea}
                        maxLength={500}
                        name={inputNames.DESCRIPTION}
                        placeholder="More about your portfolio’s purpose and approach"
                        resize
                    />
                </section>
                <Form.SubmitTrigger
                    render={({submit}) => (
                        <Button
                            className={createButtonClassName}
                            variant="primary"
                            text="Create"
                            onClick={submit}
                        />
                    )}
                />
            </Form>
        )
    }
}

PortfolioCreationForm.propTypes = {
    createPortfolio: PropTypes.func,
    data: PropTypes.shape({
        [inputNames.NAME]: PropTypes.string,
        [inputNames.FUNDING_AMOUNT]: PropTypes.object,
        [inputNames.INVESTMENT_APPROACH]: PropTypes.string,
        [inputNames.DESCRIPTION]: PropTypes.string,
    }),
    error: PropTypes.shape({
        [inputNames.NAME]: PropTypes.string,
        [inputNames.FUNDING_AMOUNT]: PropTypes.string,
        [inputNames.INVESTMENT_APPROACH]: PropTypes.string,
        [inputNames.DESCRIPTION]: PropTypes.string,
    }),
    isPremiumUser: PropTypes.bool,
    validateOnUpdate: PropTypes.bool,
    onChange: PropTypes.func,
    onError: PropTypes.func,
    onSubmit: PropTypes.func,
}

PortfolioCreationForm.defaultProps = {
    data: {...PortfolioCreationForm.defaultState.data},
    error: {...PortfolioCreationForm.defaultState.error},
    validateOnUpdate: true,
}

export default PortfolioCreationForm
