import React, { FC } from 'react';
import * as Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';
import SeriesIcon from 'src/components/seriesIcon';
import { formatNumber } from 'src/utils/formatNumber';
import { formatMessage } from '@orchard/frontend-localization';
import { EMPTY_CHAR } from 'src/components/metric';
import cx from 'classnames';
import { MIN_PIE_CHART_SIZE } from 'src/constants/graphs';

export const CLASSNAME = 'StreamsBySubscriptionChart';
export const CLASSNAME_CHART = `${CLASSNAME}-chart`;
export const CLASSNAME_TABLE = `${CLASSNAME}-table`;
export const CLASSNAME_ROW = `${CLASSNAME}-row`;
export const CLASSNAME_ROW_FIRST = `${CLASSNAME}-row-first`;
export const CLASSNAME_ROW_SECOND = `${CLASSNAME}-row-second`;
export const CLASSNAME_ROW_THIRD = `${CLASSNAME}-row-third`;
export const TEST_ID = CLASSNAME;

type PercentageData = {
    percentage: number;
};

type CustomData = {
    custom?: PercentageData;
};

const DEFAULT_CHART_OPTIONS = () => ({
    chart: {
        type: 'pie',
        styledMode: true,
        height: 100,
        margin: [0, 0, 0, 0],
        spacing: [0, 0, 0, 0],
        border: 0
    },
    title: { text: '' },
    credits: { enabled: false },
    legend: { enabled: false },
    plotOptions: {
        pie: {
            allowPointSelect: false,
            innerSize: '70%',
            dataLabels: {
                enabled: false
            }
        },
        series: {
            enableMouseTracking: true,
            states: {
                hover: {
                    enabled: true,
                    halo: {
                        size: 0,
                    }
                },
            }
        }
    }
});

const hasValue = (data: ChartPoint[]) => (
    data.some(point => point.value !== 0)
);

function toolTipFormatter(this: Highcharts.TooltipFormatterContextObject) {
    const { custom: { percentage } = {} } = this.point as CustomData;
    const percentageValue = percentage || this.percentage;
    return `<div class="highcharts-tooltip-container">
                <div class="highcharts-tooltip-data">
                <span class="highcharts-tooltip-value">${Highcharts.numberFormat(percentageValue as number, 2)}%</span>
            </div></div>`;
}

const createChartOptions = (index: number, data: NormalizedChartPoint[]) => ({
    ...DEFAULT_CHART_OPTIONS(),
    chart: {
        ...DEFAULT_CHART_OPTIONS().chart,
        className: `stroke-dataviz-${index}`
    },
    series: [{
        type: 'pie',
        data: data.map(({ value, label, percentage }, subIndex) => ({
            name: label,
            custom: { percentage },
            y: value,
            className: cx(`bg-dataviz-${index}-${subIndex}`, { 'no-data': !hasValue(data) })
        }))
    }],
    tooltip: {
        useHTML: true,
        formatter: toolTipFormatter,
    }
}) as Highcharts.Options;

interface ChartPoint {
    value: number | null;
    label: string;
}

interface NormalizedChartPoint extends ChartPoint {
    percentage: number;
}

export interface Props {
    data: ChartPoint[];
    index: number;
}

const StreamsBySubscriptionChart: FC<Props> = ({ index, data }) => {
    const total = data.reduce((sum, { value }) => (value ? value + sum : sum), 0);
    const normalizedData = data.map<NormalizedChartPoint>(({ label, value }) => ({
        label,
        value: value ? Math.max(value, total * (MIN_PIE_CHART_SIZE / 100)) : value,
        percentage: value && total ? (value / total) * 100 : 0,
    }));

    const chartOptions = createChartOptions(index, normalizedData);
    const noData = !hasValue(data);

    return (
        <div className={CLASSNAME} data-testid={TEST_ID}>
            <div className={CLASSNAME_CHART}>
                <HighchartsReact highcharts={Highcharts} options={chartOptions} />
            </div>
            <div className={CLASSNAME_TABLE}>
                {data.map(({ label, value }, subIndex) => (
                    <div className={CLASSNAME_ROW} key={label}>
                        <div className={CLASSNAME_ROW_FIRST}><SeriesIcon index={index} subIndex={subIndex} /></div>
                        <div className={CLASSNAME_ROW_SECOND}>{formatMessage(label)}</div>
                        <div className={CLASSNAME_ROW_THIRD}>
                            {value === undefined || value === null || noData ? EMPTY_CHAR : formatNumber(value)}
                        </div>
                    </div>
                ))}
            </div>
        </div>
    );
};

export default StreamsBySubscriptionChart;
