import React from 'react'
import PropTypes from 'prop-types'
import ModalForm from 'react-uikit/modal/form'
import OptionHeader from 'components/option/header'
import OptionPortfolioInfo from 'components/option/portfolio-info'
import OptionExerciseForm from 'containers/forms/option-exercise'
import inputNames from 'common-fe/constants/input-names'
import securityTypes from 'common-fe/constants/security-types'
import {Provider, withContext} from './context'

class ExerciseOptionModal extends React.PureComponent {
    static OptionHeader = withContext(OptionHeader)
    static OptionPortfolioInfo = withContext(OptionPortfolioInfo)
    static OptionExerciseForm = withContext(OptionExerciseForm)

    state = {exerciseQuantity: 0}

    get childContext() {
        const {portfolio, security, underlyingSecurity} = this.props

        return {
            portfolio,
            security,
            underlyingSecurity,
        }
    }

    componentDidMount() {
        const {
            shouldSubscribe,
            subscribeToSecurity,
            underlyingSecurity: {id: securityId, exchange, securityType},
        } = this.props

        // We don't want to subscribe to BONDS since they aren't
        // very volatile. Also, because we don't have a socket for it.
        const canSubscribe = securityType !== securityTypes.BOND.value

        canSubscribe &&
            shouldSubscribe &&
            subscribeToSecurity &&
            subscribeToSecurity({exchange, securityId})
    }

    componentDidUpdate(prevProps) {
        const {
            isShowing,
            shouldSubscribe,
            subscribeToSecurity,
            underlyingSecurity: {id: securityId, exchange, type: securityType},
            unsubscribeToSecurity,
        } = this.props

        // We handle show/hide changes here rather than in mount/unmount lifecycle
        // methods because our modals do not unmount unless the modal manager
        // is switching between modal templates. The update lifecycle will be
        // more reliable for side effects of show/hide.
        if (!prevProps.isShowing && isShowing) {
            const canSubscribe = securityType !== securityTypes.BOND.value

            canSubscribe &&
                shouldSubscribe &&
                subscribeToSecurity &&
                subscribeToSecurity({exchange, securityId})
        }

        if (prevProps.isShowing && !isShowing) {
            const canSubscribe = securityType !== securityTypes.BOND.value

            canSubscribe &&
                shouldSubscribe &&
                unsubscribeToSecurity &&
                unsubscribeToSecurity({exchange, securityId})
        }
    }

    onFormChange = ({[inputNames.ORDER_QUANTITY]: exerciseQuantity}) => {
        if (exerciseQuantity !== this.state.exerciseQuantity) {
            this.setState({exerciseQuantity})
        }
    }

    render() {
        const {exerciseQuantity} = this.state
        const {isShowing, onDismiss} = this.props

        return (
            <ModalForm
                isShowing={isShowing}
                title="Exercise Option"
                onDismiss={onDismiss}
            >
                <Provider value={this.childContext}>
                    <ExerciseOptionModal.OptionHeader />
                    <ExerciseOptionModal.OptionPortfolioInfo
                        exerciseQuantity={exerciseQuantity}
                    />
                    <ExerciseOptionModal.OptionExerciseForm
                        unregisterOnExit
                        onChange={this.onFormChange}
                        onSubmit={onDismiss}
                    />
                </Provider>
            </ModalForm>
        )
    }
}

ExerciseOptionModal.propTypes = {
    isShowing: PropTypes.bool,
    portfolio: PropTypes.object,
    security: PropTypes.object,
    shouldSubscribe: PropTypes.bool,
    subscribeToSecurity: PropTypes.func,
    underlyingSecurity: PropTypes.object,
    unsubscribeToSecurity: PropTypes.func,
    onDismiss: PropTypes.func,
}

export default ExerciseOptionModal
