import React, {useEffect} from 'react'
import PropTypes from 'prop-types'
import LogRocket from 'logrocket'
import inputNames from 'common-fe/constants/input-names'
import orderActions from 'common-fe/constants/order-actions'
import securityTypes from 'common-fe/constants/security-types'
import {
    renderPercentDisplay,
    renderLargeNumber,
    renderWithCurrency,
} from 'common-fe/utils/render'
import modalTypes from 'containers/modal-manager/modal-types'
import {
    getCurrency,
    getCurrencyValue,
    getHolding,
    getHoldingMarketValue,
    getHoldingsBySecurityType,
} from 'utils/portfolio'

import ChangePill from 'react-uikit/change-pill'
import HoldingDatum from 'components/order/holding-datum'
import Icon from 'react-uikit/icon'
import Layout from 'react-uikit/layout'

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

const getHoldingsLabel = (securityType) => {
    switch (securityType) {
        case securityTypes.EQUITY.value:
            return 'Stocks Owned'

        case securityTypes.FUND.value:
            return 'ETFs Owned'

        case securityTypes.BOND.value:
            return 'Bonds Owned'

        case securityTypes.OPTION.value:
            return 'Contracts Owned'

        default:
            return 'Securities Owned'
    }
}

const OrderPortfolioInfo = ({
    className,
    orderDetails,
    portfolio,
    security,
    showModal,
}) => {
    const {holdings: securities} = portfolio
    const {currency, id: securityId, type: securityType} = security
    const holdings = getHoldingsBySecurityType({securities}, securityType)
    const securityHolding = getHolding({holdings, securityId})

    // (1) Securities Owned
    const holdingsLabel = getHoldingsLabel(securityType)
    const {quantity: holdingQuantity, purchaseCost} = securityHolding
    const quantity = holdingQuantity === null ? 0 : holdingQuantity

    // (2) Market Value
    // Re-calculate market value using up-to-date security object
    const marketValue = getHoldingMarketValue({
        holding: securityHolding,
        security,
    })
    const marketValueDisplay = renderWithCurrency(marketValue, currency, {
        decimal: 0,
        largeNumber: true,
    })

    // (3) Total Return
    // Re-calculate profit loss based on up-to-date market value
    const profitLoss = marketValue - purchaseCost
    const percentChange =
        (profitLoss / (Number(Math.abs(marketValue).toFixed(2)) - profitLoss)) *
        100

    const change =
        quantity === 0
            ? {percentDisplay: '0.00', value: 0}
            : {
                  percentDisplay: renderPercentDisplay(percentChange),
                  value: profitLoss,
              }

    // (4) Cash (available in the security’s currency)
    const currencyPosition = getCurrency({holdings: securities.cash, currency})
    const {amount: currencyValue = 0} =
        getCurrencyValue({
            holdings: securities.cash,
            currency,
        }) || {}
    const isEnoughCurrency =
        (currencyValue >= orderDetails.estimatedPrice &&
            (orderDetails[inputNames.ORDER_ACTION] === orderActions.BUY.value ||
                orderDetails[inputNames.ORDER_ACTION] ===
                    orderActions.COVER.value)) ||
        (orderDetails[inputNames.ORDER_ACTION] !== orderActions.BUY.value &&
            orderDetails[inputNames.ORDER_ACTION] !== orderActions.COVER.value)

    const showTradingModal = () => {
        const {
            [inputNames.ORDER_ACTION]: orderAction,
            [inputNames.ORDER_QUANTITY]: orderQuantity,
            orderActionOptionsItemIndex,
        } = orderDetails || {}
        showModal?.({
            type: modalTypes.MODAL_ORDER,
            securityId,
            shouldSubscribe: true,
            [inputNames.ORDER_ACTION]: orderAction,
            [inputNames.ORDER_QUANTITY]: orderQuantity,
            orderActionOptionsItemIndex,
        })
    }

    const handleCurrencyExchange = () => {
        showModal?.({
            type: modalTypes.MODAL_CURRENCY_EXCHANGE,
            onDismiss: showTradingModal,
        })
    }

    useEffect(() => {
        if (!isEnoughCurrency) {
            LogRocket.track('Trading - Insufficient Currency')
        }
    }, [currencyValue, orderDetails[inputNames.ORDER_ACTION]])

    const rootClassNames = bem.classNames('c-order-portfolio-info', className)
    const portfolioInfoHoldingsClasses = bem.classNames(
        'c-order-portfolio-info__holdings'
    )
    const portfolioInfoHrClasses = bem.classNames('c-order-portfolio-info__hr')
    const portfolioInfoCashClasses = bem.classNames(
        'c-order-portfolio-info__cash'
    )
    const portfolioInfoCashHeadingClasses = bem.classNames(
        'c-order-portfolio-info__cash-heading'
    )
    const portfolioInfoCashDatumClasses = bem.classNames(
        'c-order-portfolio-info__cash-datum'
    )

    const portfolioInfoCashErrorClasses = bem.classNames(
        'c-order-portfolio-info__cash-error'
    )

    const currencyExchangeButtonClasses = bem.classNames(
        'c-order-portfolio-info__currency-exchange-button'
    )

    return (
        <section className={rootClassNames} key="portfolio-info">
            <div className={portfolioInfoHoldingsClasses}>
                <HoldingDatum
                    title={holdingsLabel}
                    value={renderLargeNumber(quantity)}
                />

                <HoldingDatum title="Market Value" value={marketValueDisplay} />

                <HoldingDatum
                    title="Total Return"
                    render={() => (
                        <ChangePill
                            size="medium"
                            value={`${renderWithCurrency(
                                change.value,
                                currency,
                                {largeNumber: true}
                            )} (${change.percentDisplay}%)`}
                            isPositive={
                                change.value === 0
                                    ? undefined
                                    : change.value > 0
                            }
                        />
                    )}
                />
            </div>

            <hr className={portfolioInfoHrClasses} />

            <div className={portfolioInfoCashClasses}>
                <div className={portfolioInfoCashHeadingClasses}>
                    <Layout.Flex align="center">
                        <Icon name="wallet" style={{maxWidth: '2rem'}} />
                        &ensp;
                        <span>Cash</span>
                    </Layout.Flex>
                    <span>{currency}</span>
                </div>

                <div className={portfolioInfoCashDatumClasses}>
                    {currencyPosition}
                </div>

                <button
                    className={currencyExchangeButtonClasses}
                    onClick={handleCurrencyExchange}
                >
                    Currency Exchange
                </button>

                {!isEnoughCurrency && (
                    <span className={portfolioInfoCashErrorClasses}>
                        Your {currency} balance is too low. Sell {currency}{' '}
                        securities or exchange currencies to complete this
                        order.
                    </span>
                )}
            </div>
        </section>
    )
}

OrderPortfolioInfo.propTypes = {
    className: PropTypes.string,
    orderDetails: PropTypes.object,
    portfolio: PropTypes.object,
    security: PropTypes.shape({
        currency: PropTypes.string, // 'USD'
        currentPrice: PropTypes.number, // '120.30.'
        id: PropTypes.string, // 'AAPL.O'
        type: PropTypes.string, // 'BOND'
    }),
    showModal: PropTypes.func,
}

export default OrderPortfolioInfo
