/* eslint-disable indent */
import React, {lazy, Suspense} from 'react'
import PropTypes from 'prop-types'
const Chart = lazy(() => import('react-uikit/chart'))
const ChartBlank = lazy(() => import('react-uikit/chart/partials/chart-blank'))
import Layout from 'react-uikit/layout'
import securityTypes from 'common-fe/constants/security-types'
import ChartTemplate from './partials/chart-template'
import ChangePill from 'react-uikit/change-pill'
import BEMModule from 'utils/bem'
import styles from './styles.scss'
const bem = new BEMModule(styles)

const getChartMessage = ({isLoading, isReady, isSingleHolding}) => {
    const messageFetchFail =
        'There seems to be a problem, please try again later.'
    const messageFetchingData = 'Retrieving data...'
    const messageMinThreeDays =
        'To evaluate the effect this holding has on your Sharpe Ratio, you need to have made at least one trade and then 3 days must elapse.'
    const messageSingleHolding =
        'To evaluate the effect this holding has on your Sharpe Ratio, you need more than one holding in your portfolio.'

    if (isLoading) {
        return messageFetchingData
    }

    if (isSingleHolding) {
        return messageSingleHolding
    }

    if (!isReady) {
        return messageMinThreeDays
    }

    return messageFetchFail
}

const makeGraphData = ({sharpeRatio, sharpeRatioMinusHolding, ts}) => {
    if (!ts || !ts.length) {
        return []
    }

    const withoutHoldingPlot = {
        color: '#BFBFBF',
        name: 'Portfolio Without Holding',
        type: 'scatter',
        x: ts,
        y: sharpeRatioMinusHolding,
    }

    const withHoldingPlot = {
        color: '#4AC0B5',
        hoverinfo: 'text',
        name: 'Portfolio',
        text: [],
        type: 'scatter',
        x: ts,
        y: sharpeRatio,
    }

    // Using a for-loop for faster enumeration
    for (let i = 0; i < ts.length; i++) {
        const sharpeDifference = sharpeRatio[i] - sharpeRatioMinusHolding[i]
        withHoldingPlot.text.push(
            `${sharpeDifference.toFixed(5)}<br>Sharpe Difference`
        )
    }

    return [withoutHoldingPlot, withHoldingPlot]
}

const BodyTemplate = ({className, effectOnSharpe, security}) => {
    const {isSingleHolding, isLoading, isError, isReady} = effectOnSharpe
    const classes = bem.classNames('c-portfolio-holdings__body', className)
    const headingClasses = bem.classNames('c-portfolio-holdings__body__heading')
    const subHeadingClasses = bem.classNames(
        'c-portfolio-holdings__body__sub-heading'
    )
    const bodyClasses = bem.classNames('c-portfolio-holdings__body__body')
    const metricItemClasses = bem.classNames(
        'c-portfolio-holdings__body__metric'
    )
    const metricLabelClasses = bem.classNames(
        'c-portfolio-holdings__body__metric-label'
    )
    const metricValueClasses = bem.classNames(
        'c-portfolio-holdings__body__metric-value'
    )
    const metricValuePillClasses = bem.classNames(
        'c-portfolio-holdings__body__metric-value-pill'
    )
    const chartContainerClasses = bem.classNames(
        'c-portfolio-holdings__body__chart-container'
    )
    const chartClasses = bem.classNames('c-portfolio-holdings__body__chart')
    const timestampClasses = bem.classNames(
        'c-portfolio-holdings__body__timestamp'
    )
    const bodyPartial = {
        [securityTypes.EQUITY.value]: security.ticker,
        [securityTypes.FUND.value]: security.ticker,
        default: 'this security',
    }
    const body = `We calculated the difference in Sharpe Ratio between your portfolio and an identical portfolio that didn’t hold ${
        bodyPartial[security.type] || 'this security'
    }.`
    const lastUpdated = effectOnSharpe.hasOwnProperty('sharpeDifference')
        ? ''
        : 'Minimum 3 days needed to calculate Sharpe Ratio'

    const graphData = makeGraphData(effectOnSharpe)
    const isBlank = isLoading || isError || isSingleHolding || !graphData.length

    return (
        <div className={classes}>
            <Layout.Flex direction="column">
                <h1 className={headingClasses}>Influence on Sharpe Ratio</h1>
                <p className={bodyClasses}>{body}</p>

                <Layout.Flex direction="column">
                    <span className={subHeadingClasses}>
                        {`By Holding ${
                            bodyPartial[security.type] ||
                            `this ${securityTypes[security.type].label}`
                        }`}
                    </span>
                    <div className={metricItemClasses}>
                        <span className={metricLabelClasses}>
                            Sharpe Ratio Difference:
                        </span>
                        <span className={metricValueClasses}>
                            {isNaN(effectOnSharpe.sharpeDifferenceDisplay) ||
                            isBlank ? (
                                `N/A`
                            ) : (
                                <ChangePill
                                    isPositive={
                                        effectOnSharpe.hasOwnProperty(
                                            'sharpeDifference'
                                        ) &&
                                        effectOnSharpe.sharpeDifference !== 0
                                            ? effectOnSharpe.sharpeDifference >
                                              0
                                            : undefined
                                    }
                                    value={
                                        effectOnSharpe.sharpeDifferenceDisplay
                                    }
                                />
                            )}
                        </span>
                    </div>

                    <div className={metricItemClasses}>
                        <span className={metricLabelClasses}>
                            Volatility Difference:
                        </span>
                        <span className={metricValueClasses}>
                            {isNaN(effectOnSharpe.volatilityDifference) ||
                            isBlank ? (
                                `N/A`
                            ) : (
                                <ChangePill
                                    className={metricValuePillClasses}
                                    isPositive={
                                        effectOnSharpe.hasOwnProperty(
                                            'volatilityDifference'
                                        ) &&
                                        effectOnSharpe.volatilityDifference !==
                                            0
                                            ? effectOnSharpe.volatilityDifference >
                                              0
                                            : undefined
                                    }
                                    value={
                                        effectOnSharpe.volatilityDifferenceDisplay
                                    }
                                />
                            )}
                        </span>
                    </div>

                    <div className={metricItemClasses}>
                        <span className={metricLabelClasses}>
                            Difference in Avg. Daily Return:
                        </span>
                        <span className={metricValueClasses}>
                            {isNaN(effectOnSharpe.returnDifference) ||
                            isBlank ? (
                                `N/A`
                            ) : (
                                <ChangePill
                                    className={metricValuePillClasses}
                                    isPositive={
                                        effectOnSharpe.hasOwnProperty(
                                            'returnDifference'
                                        ) &&
                                        effectOnSharpe.returnDifference !== 0
                                            ? effectOnSharpe.returnDifference >
                                              0
                                            : undefined
                                    }
                                    value={
                                        effectOnSharpe.returnDifferenceDisplay
                                    }
                                />
                            )}
                        </span>
                    </div>
                    <div className={timestampClasses}>{lastUpdated}</div>
                </Layout.Flex>
            </Layout.Flex>

            <div className={chartContainerClasses}>
                <Suspense fallback={null}>
                    <Chart
                        className={chartClasses}
                        isBlank={isBlank}
                        renderBlank={() => (
                            <ChartBlank
                                message={getChartMessage({
                                    isLoading,
                                    isReady,
                                    isSingleHolding,
                                })}
                            />
                        )}
                        data={graphData}
                        template={ChartTemplate}
                    />
                </Suspense>
            </div>
        </div>
    )
}

BodyTemplate.propTypes = {
    className: PropTypes.string,
    effectOnSharpe: PropTypes.object,
    security: PropTypes.object,
}

export default BodyTemplate
