import React from 'react'
import PropTypes from 'prop-types'
import {safeToFixed} from 'common-fe/utils'
import requestStatuses from 'common-fe/constants/request-statuses'
import content from './content'
import {getSharpeRatioGrade} from 'utils/metrics'

import Banner from 'components/banner'
import Icon from 'react-uikit/icon'
import Tooltip from 'react-uikit/tooltip'

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

const RankingSharpeRatioFormula = ({
    className,
    currentPeriod,
    isPublic,
    jumpToRank,
    metrics,
    name,
    portfolio,
    periodDisplay,
    portfolioRanking,
}) => {
    const {
        sharpe: {
            [currentPeriod]: {
                avgRiskFreeRate: riskFreeRate = 0,
                avgReturnRate: avgReturn = 0,
                stdReturnRate: avgReturnStd = 0,
                value: sharpeRatio,
                valueDisplay,
                errors,
            } = {},
        } = {},
        status,
    } = metrics || {}
    const isLoading = status === requestStatuses.PENDING
    const {[currentPeriod]: {rank} = {}} = portfolioRanking || {}
    const {isCoursePortfolio, isCourseEnded} = portfolio || {}
    const avgReturnDisplay = safeToFixed(avgReturn * 100, 4)
    const riskFreeRateDisplay = safeToFixed(riskFreeRate * 100, 4)
    const avgReturnStdDisplay = safeToFixed(avgReturnStd * 100, 4)
    const grade = {
        ...getSharpeRatioGrade({sharpeRatio}),
        link: content.generalLink,
    }

    const rootClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula',
        className
    )
    const constantClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__constant'
    )
    const gradeClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__grade',
        {[grade.value]: grade.value}
    )
    const formulaClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__formula'
    )
    const labelClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__label'
    )
    const numberClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__number'
    )
    const sharpeRatioClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__sharpe-ratio'
    )
    const valueClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__value'
    )
    const valueLabelClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__value-label'
    )
    const valueRankClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__value-rank'
    )
    const privateLabelClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__private'
    )
    const signClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__sign'
    )
    const tooltipClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__tooltip'
    )
    const errorClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__error'
    )
    const linkClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__link'
    )
    const isLoadingClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__loader'
    )
    const helpIconClassNames = bem.classNames(
        'c-ranking-sharpe-ratio-formula__icon'
    )

    if (errors) {
        return (
            <div className={errorClassNames}>
                {errors.find((error) => error.code === 4900) ? (
                    <Banner info>
                        {name} portfolio doesn’t have {periodDisplay} worth of
                        data points yet. Keep managing your portfolio and you
                        will see it on the Leaderboard soon!
                    </Banner>
                ) : (
                    <Banner warning>{errors[0].reason}.</Banner>
                )}
                <p>
                    Remember, the longer the period, the harder it gets to keep
                    a high Sharpe Ratio.
                </p>
            </div>
        )
    }

    let rankMessage = null

    if (!isPublic) {
        rankMessage = (
            <div
                className={privateLabelClassNames}
                data-tip=""
                data-for="privatePortfolio"
            >
                Portfolio is <em>Private</em>.
                <Icon name="tab-support" className={helpIconClassNames} />
                <Tooltip
                    id="privatePortfolio"
                    className={tooltipClassNames}
                    isDark
                    place="bottom"
                >
                    <p>
                        {name} portfolio is Private, which means it won’t appear
                        on the Leaderboard or have a rank.
                    </p>
                </Tooltip>
            </div>
        )
    } else if (isCoursePortfolio && isCourseEnded) {
        rankMessage = (
            <div
                className={privateLabelClassNames}
                data-tip=""
                data-for="challengePortfolio"
            >
                {name} is no longer ranked.
                <Icon name="tab-support" className={helpIconClassNames} />
                <Tooltip
                    id="challengePortfolio"
                    className={tooltipClassNames}
                    isDark
                    place="bottom"
                >
                    <p>
                        Challenge portfolios are no longer active once a
                        Challenge has ended, which means it won’t appear on the
                        Leaderboard or have a rank. Start a new portfolio to be
                        ranked.
                    </p>
                </Tooltip>
            </div>
        )
    } else {
        rankMessage = (
            <h3 className={valueLabelClassNames}>
                {!rank ? (
                    <span className={isLoadingClassNames}>&nbsp;</span>
                ) : (
                    <span className={valueClassNames}>{rank || '–'}</span>
                )}
                <span className={valueRankClassNames}>Rank</span>
            </h3>
        )
    }

    return (
        <div className={rootClassNames}>
            <section className={sharpeRatioClassNames}>
                <p className={gradeClassNames}>{grade.label}</p>
                <div>
                    <h3 className={valueLabelClassNames}>
                        {isLoading ? (
                            <span className={isLoadingClassNames}>&nbsp;</span>
                        ) : (
                            <span className={valueClassNames}>
                                {valueDisplay}
                            </span>
                        )}
                        <span>Sharpe Ratio</span>
                    </h3>
                </div>
                <div>{rankMessage}</div>
                <div>
                    <a
                        className={linkClassNames}
                        href={grade.link}
                        target="_blank"
                        rel="noreferrer noopener"
                    >
                        How to improve?
                    </a>
                </div>
                <div>
                    {isPublic && !isCourseEnded && (
                        <button className={linkClassNames} onClick={jumpToRank}>
                            Jump to your rank
                        </button>
                    )}
                </div>
            </section>
            <dl className={formulaClassNames}>
                <span className={signClassNames}>(</span>
                <dt
                    className={labelClassNames}
                    data-tip=""
                    data-for="avgReturn"
                >
                    Avg Return Rate
                    <Tooltip
                        id="avgReturn"
                        direction="left"
                        className={tooltipClassNames}
                        isDark
                    >
                        <p>{content.avgReturn}</p>
                    </Tooltip>
                </dt>
                <dd className={numberClassNames}>
                    {avgReturnDisplay}&thinsp;%
                </dd>
                <span className={signClassNames}> − </span>
                <dt
                    className={labelClassNames}
                    data-tip=""
                    data-for="riskFreeRate"
                >
                    <span className={constantClassNames}>Risk-Free Rate</span>
                    <Tooltip
                        id="riskFreeRate"
                        direction="right"
                        className={tooltipClassNames}
                        isDark
                    >
                        <p>{content.riskFreeRate}</p>
                    </Tooltip>
                </dt>
                <dd className={numberClassNames}>
                    <span className={constantClassNames}>
                        {riskFreeRateDisplay}&thinsp;%
                    </span>
                </dd>
                <span className={signClassNames}>
                    <i>)</i>
                    <i> ÷ </i>
                </span>
                <dt
                    className={labelClassNames}
                    data-tip=""
                    data-for="volatility"
                >
                    Volatility
                    <Tooltip
                        id="volatility"
                        direction="bottom"
                        className={tooltipClassNames}
                        isDark
                    >
                        <p>{content.volatility}</p>
                    </Tooltip>
                </dt>
                <dd className={numberClassNames}>
                    {avgReturnStdDisplay}&thinsp;%
                </dd>
            </dl>
        </div>
    )
}

RankingSharpeRatioFormula.propTypes = {
    className: PropTypes.string,
    currentPeriod: PropTypes.string,
    data: PropTypes.shape({
        errors: PropTypes.array,
        hasErrors: PropTypes.bool,
        isLoading: PropTypes.bool,
        name: PropTypes.string,
        rank: PropTypes.number,
        sharpe: PropTypes.shape({
            avgRiskFreeRate: PropTypes.number,
            avgReturnRate: PropTypes.number,
            stdReturnRate: PropTypes.number,
            value: PropTypes.number,
        }),
    }),
    isPublic: PropTypes.bool,
    jumpToRank: PropTypes.func,
    metrics: PropTypes.object,
    name: PropTypes.string,
    periodDisplay: PropTypes.string,
    portfolio: PropTypes.object,
    portfolioRanking: PropTypes.object,
}

export default RankingSharpeRatioFormula
