"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const highcharts_1 = require("@internal/highcharts");
const shared_1 = require("../../common/charts/shared");
const legend_1 = require("../../common/charts/legend");
const tooltip_marko_1 = __importDefault(require("./tooltip.marko"));
class AreaChart {
    onInput() {
        // if chartRef does not exist do not try to run setupCharts as it may be server side and highcharts only works on the client side
        if (this.chartRef && this.chartRef.destroy) {
            this.chartRef.destroy();
            this._setupCharts();
        }
    }
    onMount() {
        (0, highcharts_1.load)()
            .then(() => {
            this.handleSuccess();
        })
            .catch((e) => {
            this.handleError(e);
        });
    }
    handleError(err) {
        this.emit("load-error", err);
    }
    handleSuccess() {
        this._initializeHighchartExtensions();
        this._setupCharts();
    }
    getContainerId() {
        return `ebay-bar-chart-${this.id}`;
    }
    /**
     * Initialize the highchart extensions
     */
    _initializeHighchartExtensions() {
        // add custom legend wrapper function
        (0, legend_1.ebayLegend)(Highcharts);
    }
    /**
     * Set up the chart with the input data and configuration options.
     */
    _setupCharts() {
        var _a;
        // check if a single series was passed in for series and if so add it to a new array
        const series = Array.isArray(this.input.series)
            ? this.input.series
            : [this.input.series];
        (0, shared_1.setSeriesMarkerStyles)(series);
        (0, shared_1.setSeriesColors)(series);
        const config = {
            title: this.getTitleConfig(),
            chart: this.getChartConfig(),
            colors: shared_1.colorMapping,
            xAxis: this.getXAxisConfig(),
            yAxis: this.getYAxisConfig(),
            legend: this.getLegendConfig(),
            tooltip: this.getTooltipConfig(),
            plotOptions: this.getPlotOptions(),
            series, // pass in the configured series array
            credits: {
                enabled: false, // hide the highcharts label and link in the bottom right of chart
            },
        };
        // initialize and keep reference to chart
        this.chartRef = Highcharts.chart(this.getContainerId(), this._mergeConfigs(config, (_a = this.input.highchartOptions) !== null && _a !== void 0 ? _a : {}));
    }
    /**
     * Default format function for the tooltip titles
     */
    _tooltipTitleFormatter(value, dateFormat) {
        if (typeof value === "string") {
            value = parseFloat(value);
        }
        return dateFormat("%b %e, %Y", value);
    }
    /**
     * Default format function for the tooltip values
     */
    _tooltipValueFormatter(value) {
        if (typeof value === "string") {
            value = parseFloat(value);
        }
        return Intl.NumberFormat("en-US", {
            style: "currency",
            currency: "USD",
        }).format(value);
    }
    /**
     * Default format function for the yAxis labels
     */
    _yLabelFormatter(value) {
        if (typeof value === "string") {
            value = parseFloat(value);
        }
        return Intl.NumberFormat("en-US", {
            notation: "compact",
            style: "currency",
            currency: "USD",
            maximumSignificantDigits: 4,
        }).format(value);
    }
    /**
     * Merge the source Highcharts config into the target Highcharts config
     *
     * Allows for custom overrides of ebay default Highcharts configuration settings
     */
    _mergeConfigs(source, target) {
        for (const key in source) {
            if (source[key] instanceof Object)
                Object.assign(source[key], this._mergeConfigs(target[key], source[key]));
        }
        Object.assign(target || {}, source);
        return target;
    }
    /**
     * Get the title configuration for the chart
     */
    getTitleConfig() {
        return {
            text: this.input.title,
            align: "left",
            useHTML: true,
            style: {
                fontSize: "18px",
                fontWeight: "700",
            },
        };
    }
    /**
     * Get the chart configuration for the chart
     */
    getChartConfig() {
        var _a;
        const type = (_a = this.input.areaType) !== null && _a !== void 0 ? _a : "areaspline";
        return {
            type,
            animation: false,
            backgroundColor: shared_1.backgroundColor,
            style: {
                fontFamily: shared_1.chartFontFamily,
            },
        };
    }
    /**
     * Get the xAxis configuration for the chart
     */
    getXAxisConfig() {
        const xLabelFormatter = this.input.xLabelFormatter;
        return {
            // currently setup to support epoch time values for xAxisLabels.
            // It is possible to set custom non datetime xAxisLabels but will need changes to this component
            type: "datetime",
            labels: {
                formatter: xLabelFormatter
                    ? function () {
                        return xLabelFormatter === null || xLabelFormatter === void 0 ? void 0 : xLabelFormatter(this.value, Highcharts.dateFormat);
                    }
                    : undefined,
                format: "{value:%b %e}",
                align: "center",
                style: {
                    color: shared_1.labelsColor,
                },
            },
            tickWidth: 0, // hide the vertical tick on xAxis labels
            crosshair: {
                color: "rgba(0, 0, 0, 0.2)",
                zIndex: 3,
            },
        };
    }
    /**
     * Get the yAxis configuration for the chart
     */
    getYAxisConfig() {
        var _a;
        // Formatter function for the yAxis labels
        const yLabelFormatter = (_a = this.input.yLabelFormatter) !== null && _a !== void 0 ? _a : this._yLabelFormatter;
        return {
            gridLineColor: shared_1.gridColor,
            opposite: true, // moves yAxis labels to the right side of the chart
            reversedStacks: false, // makes so series one starts at the bottom of the yAxis, by default this is true
            labels: {
                formatter: function () {
                    return yLabelFormatter(this.value);
                },
                style: {
                    color: shared_1.labelsColor,
                },
            },
            title: {
                enabled: false,
            },
            offset: 0,
        };
    }
    /**
     * Get the legend configuration for the chart
     */
    getLegendConfig() {
        return {
            // If only a single series is provided do not display the legend
            enabled: Array.isArray(this.input.series) &&
                this.input.series.length > 1,
            symbolRadius: 2,
            symbolWidth: 12,
            symbolHeight: 12,
            itemStyle: {
                color: shared_1.legendColor,
                fontWeight: "normal",
            },
            align: "left",
            itemHiddenStyle: {
                color: shared_1.legendInactiveColor,
            },
            itemHoverStyle: {
                color: shared_1.legendHoverColor,
            },
        };
    }
    /**
     * Get the tooltip configuration for the chart
     */
    getTooltipConfig() {
        var _a, _b;
        const tooltipValueFormatter = (_a = this.input.tooltipValueFormatter) !== null && _a !== void 0 ? _a : this._tooltipValueFormatter;
        const tooltipTitleFormatter = (_b = this.input.tooltipTitleFormatter) !== null && _b !== void 0 ? _b : this._tooltipTitleFormatter;
        return {
            formatter: function () {
                var _a;
                const date = tooltipTitleFormatter((_a = this.x) !== null && _a !== void 0 ? _a : 0, Highcharts.dateFormat);
                // Display formatted total, only if there are more than one points
                const total = this.points &&
                    this.points.length > 1 &&
                    this.points.reduce((acc, curr) => { var _a; return acc + ((_a = curr.y) !== null && _a !== void 0 ? _a : 0) * 100; }, 0) / 100;
                return tooltip_marko_1.default.renderToString({
                    date,
                    total: total || 0,
                    points: this.points,
                    valueFormatter: tooltipValueFormatter,
                });
            },
            useHTML: true,
            backgroundColor: shared_1.tooltipBackgroundColor,
            borderWidth: 0,
            borderRadius: 10,
            outside: true,
            shadow: false,
            shared: true,
            style: {
                filter: shared_1.tooltipShadows,
                fontSize: "12px",
            },
        };
    }
    /**
     * Get the plot options configuration for the chart
     */
    getPlotOptions() {
        var _a;
        const type = (_a = this.input.areaType) !== null && _a !== void 0 ? _a : "areaspline";
        return {
            series: {
                accessibility: {
                    description: this.input.description,
                },
                stacking: "normal",
                states: {
                    hover: {
                        halo: { size: 0 },
                    },
                },
                marker: {
                    enabled: false,
                    animation: { duration: 0 },
                },
            },
            [type]: {
                className: "ebay-area-chart",
                lineWidth: 1,
            },
        };
    }
    onDestroy() {
        var _a;
        (_a = this.chartRef) === null || _a === void 0 ? void 0 : _a.destroy();
    }
}
module.exports = AreaChart;
