import React, {lazy, Suspense, useCallback, useEffect, useMemo} from 'react'
import {useSelector} from 'react-redux'
import PropTypes from 'prop-types'
import hoistNonReactStatics from 'hoist-non-react-statics'
import {Link} from 'react-router-dom'
const Chart = lazy(() => import('react-uikit/chart'))
import Tooltip from 'react-uikit/tooltip'
import TradeButton from 'components/trade-button'
import {SUBSCRIPTION_FREE_SECURITY_TYPES} from 'store/config'
import routes from 'global/constants/routes'
import {safeToFixed} from 'common-fe/utils'
import styles from './styles.scss'
import {makeGetSecurityMarketValueTimeseries} from 'store/selectors'

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

const PLACEHOLDER_TIMESERIES = [
    {x: ['2018-05-30', '2018-05-31'], y: [1, 1], color: '#BFBFBF'},
]

const baseETFs = {
    SPY: {heading: 'USA [Stock]', description: '500 Largest Companies'},
    EEM: {
        heading: 'Brazil, Russia, India, China [Stock]',
        description: '1,000 Largest Companies',
    },
    VGK: {heading: 'Europe [Stock]', description: '1,000 Largest Companies'},
    IBDN: {heading: 'USA [Bonds]', description: '1,000 Largest Companies'},
    IEF: {heading: 'USA [Bonds]', description: 'Government'},
}

const TradeETFsTableRow = ({data, getTimeseries, policy, onTrade}) => {
    // NOTE: This creates a tight coupling with Redux. It will be wise for us
    // to think through how we can achieve selector memoization or use redux
    // hooks while not sacrificing the testability of our components.
    const getTimeseriesCloseData = useMemo(
        () => makeGetSecurityMarketValueTimeseries(data.id, 'C'),
        [data.id]
    )
    const timeseries = useSelector(getTimeseriesCloseData)
    const historicalMarketData = useMemo(() => {
        if (!timeseries || !timeseries.x.length) {
            return PLACEHOLDER_TIMESERIES
        }

        return [{x: timeseries.x, y: timeseries.y}]
    }, [timeseries])

    const handleTrade = useCallback(() => onTrade?.({securityId: data?.id}), [
        data?.id,
    ])

    useEffect(() => {
        if (data?.id) {
            getTimeseries?.({securityId: data.id}, {overrideLoader: true})
        }
    }, [data?.id, getTimeseries])

    const {
        canTrade,
        reason: {canTrade: buttonTooltip},
    } = useMemo(() => policy.forSecurity(data), [data, policy])

    if (!data) {
        return (
            <tr>
                <td>– –</td>
            </tr>
        )
    }

    const {
        currency,
        currentPriceDisplay,
        displayName,
        id,
        performance: percentDisplay,
        statistics: {volatilityDisplay, dividendYieldPercentageDisplay},
        ticker,
        type,
    } = data

    const isLocked =
        !policy.isSubscriptionActive &&
        !SUBSCRIPTION_FREE_SECURITY_TYPES.includes(type)
    const rootClassNames = bem.classNames('c-trade-etf-table-row')
    const issuerClassNames = bem.classNames('c-trade-etf-table-row__issuer')
    const captionClassNames = bem.classNames('c-trade-etf-table-row__caption')
    const performanceClassNames = bem.classNames(
        'c-trade-etf-table-row__performance'
    )
    const performanceChartClassNames = bem.classNames(
        'c-trade-etf-table-row__performance-chart'
    )
    const statisticsClassNames = bem.classNames(
        'c-trade-etf-table-row__statistics'
    )
    const numberClassNames = bem.classNames('c-trade-etf-table-row__number')
    const tooltipClassNames = bem.classNames('c-trade-etf-table-row__tooltip')

    const isBaseETF = Object.keys(baseETFs).includes(ticker)

    return (
        <tr className={rootClassNames}>
            <td>
                <span
                    className={issuerClassNames}
                    data-for={ticker}
                    data-tip={ticker}
                >
                    <Link to={`${routes.STOCK_PROFILE}/${id}`}>
                        {displayName}
                    </Link>
                </span>
                <br />
                <span className={captionClassNames}>{ticker}</span>
                {isBaseETF && (
                    <Tooltip className={tooltipClassNames} id={ticker}>
                        <strong>{baseETFs[ticker].heading}:</strong>
                        <br />
                        <span>{baseETFs[ticker].description}</span>
                    </Tooltip>
                )}
            </td>
            <td>
                <div className={performanceClassNames}>
                    <span className={captionClassNames}>3-Month</span>
                </div>
                <Suspense fallback={null}>
                    <Chart
                        data={historicalMarketData}
                        className={performanceChartClassNames}
                        type="sparkline"
                    />
                </Suspense>
            </td>
            <td>
                <dl className={statisticsClassNames}>
                    <dt>Volatility</dt>
                    <dd>{volatilityDisplay}</dd>
                    <dt>Return</dt>
                    <dd>
                        {percentDisplay
                            ? `${safeToFixed(percentDisplay, 2)}%`
                            : 'N/A'}
                    </dd>
                    <dt>Div Yield</dt>
                    <dd>{dividendYieldPercentageDisplay}</dd>
                </dl>
            </td>
            <td style={{verticalAlign: 'middle'}}>
                <span className={captionClassNames}>{currency}</span>
                <br />
                <span className={numberClassNames}>{currentPriceDisplay}</span>
            </td>
            <td>
                <TradeButton
                    disabled={!canTrade && !isLocked}
                    isLocked={isLocked}
                    tooltip={buttonTooltip}
                    onClick={handleTrade}
                />
            </td>
        </tr>
    )
}

TradeETFsTableRow.propTypes = {
    data: PropTypes.object,
    getTimeseries: PropTypes.func,
    policy: PropTypes.object,
    timeseries: PropTypes.object,
    onTrade: PropTypes.func,
}

export default hoistNonReactStatics(
    React.memo(TradeETFsTableRow),
    TradeETFsTableRow
)
