import React, {lazy, Suspense, useCallback, useEffect} from 'react'
import PropTypes from 'prop-types'
import Debug from 'common-fe/utils/debug'
import investmentApproaches from 'common-fe/constants/investment-approaches'
import {renderPercentDisplay} from 'common-fe/utils/render'
import modalTypes from 'containers/modal-manager/modal-types'
import BEMModule from 'utils/bem'

const Chart = lazy(() => import('react-uikit/chart'))

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

const portfolioApproach = (investmentApproach) => {
    if (typeof investmentApproach !== 'string') {
        return investmentApproaches.NONE.label
    }

    // eslint-disable-next-line no-prototype-builtins
    if (!investmentApproaches.hasOwnProperty(investmentApproach)) {
        Debug.error(
            `ERR: Portfolio has an unsupported investment approach: ${investmentApproach}`
        )
        return investmentApproaches.NONE.label
    }

    return investmentApproaches[investmentApproach].label
}

const BodyTemplate = React.forwardRef(
    (
        {
            getPortfolioSharpeTimeseries,
            getRankings,
            metrics,
            period,
            portfolio,
            portfolioId,
            showModal,
            sharpeTimeseries,
        },
        ref
    ) => {
        const {investmentApproach, name} = portfolio || {}
        const {
            sharpe: {
                [period]: {
                    avgReturnRate: avgReturn,
                    return: totalReturn,
                    stdReturnRate: volatility,
                } = {},
            } = {},
        } = metrics || {}

        const openPortfolioShowcase = useCallback(() => {
            showModal?.({
                type: modalTypes.MODAL_PORTFOLIO_SHOWCASE,
                portfolioId,
            })?.(portfolioId)
        }, [portfolioId])

        const avgReturnDisplay =
            typeof avgReturn === 'number'
                ? `${renderPercentDisplay(avgReturn)}%`
                : '––%'

        const volatilityDisplay =
            typeof volatility === 'number'
                ? `${renderPercentDisplay(volatility)}%`
                : '––%'

        const totalReturnDisplay =
            typeof totalReturn === 'number'
                ? `${renderPercentDisplay(totalReturn)}%`
                : '––%'

        const data = {
            portfolioReturnAverage:
                sharpeTimeseries?.portfolioReturnAverage || [],
            portfolioReturnStdMin:
                sharpeTimeseries?.portfolioReturnStdMin || [],
            portfolioReturnStdMax:
                sharpeTimeseries?.portfolioReturnStdMax || [],
            timestamps: sharpeTimeseries?.timestamps || [],
        }

        // Fetch Sharpe Timeseries
        useEffect(() => {
            if (!sharpeTimeseries?.status) {
                getPortfolioSharpeTimeseries(
                    {period, portfolioId},
                    {overrideLoader: true}
                )
            }
        }, [period])

        // Get portfolio metrics
        useEffect(() => {
            if (!metrics?.sharpe?.[period]?.value) {
                getRankings({period, portfolioId}, {overrideLoader: true})
            }
        }, [])

        const rankingTemplateClassNames = bem.classNames(
            'c-leaderboard-table-body__ranking-template'
        )
        const descriptionClassNames = bem.classNames(
            'c-leaderboard-table-body__description'
        )
        const graphClassNames = bem.classNames(
            'c-leaderboard-table-body__graph'
        )
        const labelClassNames = bem.classNames(
            'c-leaderboard-table-body__label'
        )
        const nameClassNames = bem.classNames(
            'c-leaderboard-table-body__name',
            {clickable: showModal}
        )
        const portfolioReturnClassNames = bem.classNames(
            'c-leaderboard-table-body__portfolio-return'
        )
        const portfolioApproachClassNames = bem.classNames(
            'c-leaderboard-table-body__portfolio-strategy'
        )
        const historicRateVReturn = bem.classNames(
            'c-leaderboard-table-body__historic-rate-v-return'
        )
        const volatilityRangeSwatchClassNames = bem.classNames(
            'c-leaderboard-table-body__volatility-range-swatch'
        )
        const avgReturnSwatchClassNames = bem.classNames(
            'c-leaderboard-table-body__avg-return-rate-swatch'
        )
        const statisticsClassNames = bem.classNames(
            'c-leaderboard-table-body__statistics'
        )

        return (
            <div className={rankingTemplateClassNames} ref={ref}>
                <p>&nbsp;</p>
                <p>&nbsp;</p>
                <div className={descriptionClassNames}>
                    <p className={labelClassNames}>Portfolio</p>
                    <button
                        className={nameClassNames}
                        onClick={openPortfolioShowcase}
                        style={{border: 0, backgroundColor: 'transparent'}}
                    >
                        {name}
                    </button>
                    <p className={portfolioApproachClassNames}>
                        {portfolioApproach(investmentApproach)}
                    </p>
                </div>
                <div className={historicRateVReturn}>
                    <p className={labelClassNames}>Historic Risk vs. Return</p>
                    <Suspense fallback={null}>
                        <Chart
                            className={graphClassNames}
                            type="sharpespark"
                            data={data}
                            rangeY={[-5, 5]}
                        />
                    </Suspense>
                    <div>
                        <span>
                            <i className={avgReturnSwatchClassNames} />
                            Avg. Return rate
                        </span>
                        <span>
                            <i className={volatilityRangeSwatchClassNames} />
                            Volatility level
                        </span>
                    </div>
                </div>
                <div className={portfolioReturnClassNames}>
                    <dl className={statisticsClassNames}>
                        <dt>Total Return</dt>
                        <dd>{totalReturnDisplay}</dd>
                        <dt>Avg. Return Rate</dt>
                        <dd>{avgReturnDisplay}</dd>
                        <dt>Volatility</dt>
                        <dd>{volatilityDisplay}</dd>
                    </dl>
                </div>
                <div>
                    <p>&nbsp;</p>
                </div>
            </div>
        )
    }
)

BodyTemplate.displayName = 'BodyTemplate'

BodyTemplate.propTypes = {
    getPortfolioSharpeTimeseries: PropTypes.func,
    getRankings: PropTypes.func,
    metrics: PropTypes.object,
    period: PropTypes.string,
    portfolio: PropTypes.shape({
        investmentApproach: PropTypes.string,
        name: PropTypes.string,
    }),
    portfolioId: PropTypes.string,
    sharpeTimeseries: PropTypes.PropTypes.shape({
        avgReturn: PropTypes.arrayOf(PropTypes.number),
        portfolioReturnAverage: PropTypes.arrayOf(PropTypes.number),
        portfolioReturnStdMax: PropTypes.arrayOf(PropTypes.number),
        portfolioReturnStdMin: PropTypes.arrayOf(PropTypes.number),
        volatilityMax: PropTypes.arrayOf(PropTypes.number),
        volatilityMin: PropTypes.arrayOf(PropTypes.number),
        status: PropTypes.string,
        timestamps: PropTypes.arrayOf(PropTypes.string),
    }),
    showModal: PropTypes.func,
}

export default BodyTemplate
