// $(window).on('load', function () {
window.addEventListener("load", (event) => {

    /**
     * This piece of code is used to draw the total value of a doughnut
     * in the center of itself. The value is automatically calculated
     * using the data defined in the doughnut.
     *
     *  @param {object} chart - The chartjs object
     *  @param {string} label - The label that is shown below the number.
     *  @param {number} completionRate
     *
     *  @return void
    */

    function drawDoughnutNumber(chart, label, completionRate) {
        let settings = charts.find(element => chart.id == element.chart.id)?.settings;
        if (!settings.showDoughnutTotal && !settings.showDoughnutNumber) return;
        if (!completionRate) {
            completionRate = 1;
        }
        var width = chart.width,
            height = chart.height,
            ctx = chart.ctx;

        ctx.restore();
        var fontSize = (height / 140).toFixed(2);

        ctx.fillStyle = '#333';
        ctx.textBaseline = "middle";
        ctx.font = "bold " + fontSize + "em sans-serif";

        // Draw the number
        var value = chart.data.datasets[0].data.reduce(function (x, y) {
            return x + y;
        }, 0);
        if (settings.doughnutNumberValue) {
            value = settings.doughnutNumberValue;
        }
        var valueX = Math.round((width - ctx.measureText(value).width) / 2);
        var valueY = height / 2 + (fontSize * 2);
        var valueWithCompletionRate = Math.round(value * completionRate);
        ctx.fillText(valueWithCompletionRate.toLocaleString(settings.locale || 'de-CH'), valueX, valueY);
        // Draw the label
        ctx.fillStyle = '#666';
        fontSize = (height / 350).toFixed(2);
        ctx.font = fontSize + "em sans-serif";
        var textX = Math.round((width - ctx.measureText(label).width) / 2);
        var textY = height / 2 - (fontSize * 25);
        ctx.fillText(label, textX, textY);

        ctx.save();
    }
    let charts = [];
    // let doughnutNumberValue = 0;
    // reset doughnutNumber to 0 to go back to default animation behaviour
    Chart.register({
        id: 'customMouseOut',
        beforeEvent(chart, args, pluginOptions) {
            if (args.event.type === 'mouseout') {
                let newValue = 0;
                chart.data.datasets[0].data.forEach((value, i) => {
                    if (!chart._hiddenIndices[i]) {
                        newValue += value;
                    }
                });
                let settings = charts.find(element => chart.id == element.chart.id)?.settings;
                settings.doughnutNumberValue = newValue;
                settings.showDoughnutNumber = false;
            }
        },
    });
    Chart.defaults.animationSteps = 60;
    Chart.defaults.responsive = true;
    Chart.defaults.maintainAspectRatio = true;
    Chart.defaults.responsiveAnimationDuration = 1000;

    // Only render the charts if they are inside of the viewport
    // this improves the performance, especially on mobile devices.
    //$('.ig-chart').one('inview', function (event, visible) {
    let chartElements = document.getElementsByClassName('ig-chart');
    for (let element of chartElements) {
        // for (let index = 0; index < chartElements.length; index++) {
        let inview = InView(element, function (visible) {
            if (visible && !element.classList.contains('loaded')) {
                //let element = chartElements[index];

                var ctx = element,
                    chartType = element.dataset.charttype,
                    showLegend = element.dataset.showlegend,
                    disableTooltipData = Boolean(element.dataset.disabletooltipdata),
                    yScaleSuffix = element.dataset.yscalesuffix,
                    xScaleSuffix = element.dataset.xscalesuffix,
                    data = JSON.parse(element.dataset.chart);
                var chartSettings = {
                    // Doughnut specific options
                    cutoutPercentage: element.dataset.cutoutpercentage,
                    showDoughnutTotal: parseInt(element.dataset.showdoughnuttotal),
                    doughnutTotalSuffix: element.dataset.doughnuttotalsuffix,

                    // Scale options
                    showXScale: element.dataset.showxscale,
                    showYScale: element.dataset.showyscale,
                    yStepSize: element.dataset.ystepsize,
                    yScaleMax: element.dataset.yscalemax,
                    yScaleMin: element.dataset.yscalemin,
                    xStepSize: element.dataset.xstepsize,
                    xScaleMax: element.dataset.xscalemax,
                    xScaleMin: element.dataset.xscalemin,
                    xReverse: element.dataset.xreverse,
                    yReverse: element.dataset.yreverse,
                    xScalePosition: element.dataset.xscaleposition,
                    yScalePosition: element.dataset.yscaleposition,
                    scaleFontFamily: element.dataset.scalefontfamily,
                    scaleFontColor: element.dataset.scalefontcolor,
                    scaleFontSize: element.dataset.scalefontsize,
                    scaleFontStyle: element.dataset.scalefontstyle,

                    // Global options
                    animationDuration: element.dataset.animationduration,
                    animationEasing: element.dataset.animationeasing,
                    animationDelay: element.dataset.animationdelay,
                    locale: element.dataset.locale,
                    legendText: {},
                    doughnutNumberValue: 0,
                    doughnutNumber: false,
                    chartType: chartType,
                    showLegend: showLegend,
                    disableTooltipData: disableTooltipData,
                    yScaleSuffix: yScaleSuffix,
                    xScaleSuffix: xScaleSuffix,
                    data: data
                };
                // split labels from tooltip titles
                for (let i = 0; i < data.labels.length; i++) {
                    let split = data.labels[i].split('|');
                    if (split.length > 1) {
                        chartSettings.legendText[split[0]] = split.pop();
                    } else {
                        chartSettings.legendText[split[0]] = '';
                    }
                    data.labels[i] = split.shift();
                }
                // fix the legend on every chart type but pie
                if (data.datasets.length > 1) {
                    for (let i = 0; i < data.datasets.length; i++) {
                        data.datasets[i].label = data.datasets[i].label.split('|').shift();
                    }
                }

                var additionalOptions = JSON.parse(element.dataset.additionalOptions);
                // Setting duration for the chart animations. This setting can
                // only be applied globally for now.
                Chart.defaults.animation.duration = chartSettings.animationDuration;
                Chart.defaults.animation.easing = chartSettings.animationEasing;
                if (chartSettings.animationDelay > 0) {
                    Chart.defaults.animation.delay = function (context) {
                        return 200;
                    };
                }
                Chart.defaults.animation.onProgress = function (a) {
                    if (!a.chart.initialAnimationIsComplete) {
                        // Code for counting up the doughnut total
                        if (a.chart.config.type == 'doughnut') {// && chartSettings.showDoughnutTotal) {
                            var completionRate = a.currentStep / a.numSteps;
                            drawDoughnutNumber(a.chart, chartSettings.doughnutTotalSuffix, completionRate);
                        }
                    }
                };

                // Set default values for some of the options
                if (!chartSettings.xStepSize) {
                    chartSettings.xScaleMax = undefined
                }

                if (!chartSettings.xScaleMax) {
                    chartSettings.xScaleMax = undefined
                }

                if (!chartSettings.xScaleMin) {
                    chartSettings.xScaleMin = 0
                }

                if (!chartSettings.yStepSize) {
                    chartSettings.yScaleMax = undefined
                }

                if (!chartSettings.yScaleMax) {
                    chartSettings.yScaleMax = undefined
                }

                if (!chartSettings.yScaleMin) {
                    chartSettings.yScaleMin = 0
                }

                var options = {
                    plugins: {}
                };

                if (chartType == 'bar' || chartType == 'horizontalBar') {
                    options = {
                        hover: {
                            mode: "single"
                        },
                        tooltip: {
                            enabled: true,
                            callbacks: {
                                label: function (context) {
                                    // Depending on the bar type return the correct label
                                    if (chartType == 'bar') {
                                        return context.dataset.label + ': ' + context.parsed.y + yScaleSuffix;
                                    } else {
                                        return context.dataset.label + ': ' + context.parsed.x + xScaleSuffix;
                                    }
                                }
                            }
                        },
                        scales: {
                            x: {
                                display: chartSettings.showXScale,
                                position: chartSettings.xScalePosition,
                                reverse: chartSettings.xReverse,
                                ticks: {
                                    fontFamily: chartSettings.scaleFontFamily,
                                    fontColor: chartSettings.scaleFontColor,
                                    fontSize: chartSettings.scaleFontSize,
                                    fontStyle: chartSettings.scaleFontStyle,
                                    max: chartSettings.xScaleMax,
                                    min: chartSettings.xScaleMin,
                                    stepSize: chartSettings.xStepSize,
                                    autoSkip: false,
                                    // Adding the suffix the scale label.
                                    callback: function (value, index, values) {
                                        return '' + this.getLabelForValue(value) + xScaleSuffix;
                                    }
                                }
                            },
                            y: {
                                display: chartSettings.showYScale,
                                position: chartSettings.yScalePosition,
                                reverse: chartSettings.yReverse,
                                ticks: {
                                    fontFamily: chartSettings.scaleFontFamily,
                                    fontColor: chartSettings.scaleFontColor,
                                    fontSize: chartSettings.scaleFontSize,
                                    fontStyle: chartSettings.scaleFontStyle,
                                    max: chartSettings.yScaleMax,
                                    min: chartSettings.yScaleMin,
                                    stepSize: chartSettings.yStepSize,
                                    // Adding the suffix the scale label.
                                    callback: function (value, index, values) {
                                        return '' + this.getLabelForValue(value) + xScaleSuffix;
                                    }
                                }
                            }
                        },
                        plugins: {}
                    }
                    if (chartType == 'horizontalBar') {
                        chartType = 'bar';
                        options.indexAxis = 'y';
                    }
                }

                if (chartType == 'line') {
                    options = {
                        fill: false,
                        hover: {
                            mode: "single"
                        },
                        scales: {
                            x: {
                                display: chartSettings.showXScale,
                                position: chartSettings.xScalePosition,
                                reverse: chartSettings.xReverse,
                                ticks: {
                                    fontFamily: chartSettings.scaleFontFamily,
                                    fontColor: chartSettings.scaleFontColor,
                                    fontSize: chartSettings.scaleFontSize,
                                    fontStyle: chartSettings.scaleFontStyle,
                                    max: chartSettings.xScaleMax,
                                    min: chartSettings.xScaleMin,
                                    stepSize: chartSettings.xStepSize,
                                    // Adding the suffix the scale label.
                                    callback: function (value, index, values) {
                                        return '' + this.getLabelForValue(value) + xScaleSuffix;
                                    }
                                }
                            },
                            y: {
                                display: chartSettings.showYScale,
                                position: chartSettings.yScalePosition,
                                reverse: chartSettings.yReverse,
                                ticks: {
                                    fontFamily: chartSettings.scaleFontFamily,
                                    fontColor: chartSettings.scaleFontColor,
                                    fontSize: chartSettings.scaleFontSize,
                                    fontStyle: chartSettings.scaleFontStyle,
                                    max: chartSettings.yScaleMax,
                                    min: chartSettings.yScaleMin,
                                    stepSize: chartSettings.yStepSize,
                                    // Adding the suffix the scale label.
                                    callback: function (value, index, values) {
                                        return '' + value + yScaleSuffix;
                                    }
                                }
                            }
                        },
                        plugins: {
                            legend: {
                                display: false
                            },
                        }
                    };
                }

                if (chartType == 'radar') {
                    options = {
                        plugins: {}
                    };
                }

                // Legend settings for each chart type.

                options.plugins.legend = {
                    display: showLegend,
                    position: 'bottom'
                };
                if (chartType == 'pie' || chartType == 'doughnut') {
                    options = {
                        plugins: {
                            p1: true,
                            legend: {
                                display: false
                            },
                            tooltip: {
                                enabled: true,
				yAlign: 'bottom',
                                callbacks: {
                                    // not for real title but used for doughnutNumberValue change
                                    title: function (context) {
                                        chartSettings.doughnutNumberValue = context[0].parsed;
                                        if (chartSettings.disableTooltipData && !chartSettings.showDoughnutTotal) {
                                            chartSettings.showDoughnutNumber = true;
                                        }
                                    }
                                },
                            }
                        }
                    };
                }

                if (chartType == 'doughnut') {
                    options.cutout = chartSettings.cutoutPercentage;
                }

                if (chartSettings.disableTooltipData) {
                    if (options?.plugins?.tooltip?.enabled) {
                        options.plugins.tooltip.callbacks.label = function () {
                            return '';
                        }
                    }
                }

                options.initialAnimationIsComplete = false;

                if (typeof additionalOptions != 'undefined') {
                    Object.assign(options, additionalOptions);
                }
                options.locale = chartSettings.locale;
                // Creating the actual chart object.
                let chart = new Chart(ctx, {
                    type: chartType,
                    data: data,
                    options: options
                });
                // resize chart
                window.addEventListener('resize', () => {
                    chart.resize();
                    if (chartType == 'doughnut' && chartSettings.showDoughnutTotal) {
                        drawDoughnutNumber(chart, chartSettings.doughnutTotalSuffix, 1);
                    }
                });


                // We generate and show a custom legend for pie and doughnut
                // charts, if needed.
                if (showLegend && (chartType == "pie" || chartType == "doughnut")) {
                    let list = document.createElement('ul');
                    let data = chart.data;
                    let datasets = data.datasets;
                    let labels = data.labels;

                    list.setAttribute('class', chart.id + '-legend chart-legend ' + chartType + '-legend');
                    let items = chart.options.plugins.legend.labels.generateLabels(chart);
                    for (let index = 0; index < items.length; index++) {
                        let item = items[index];
                        let listItem = document.createElement('li');
                        listItem.classList.add('flex');
                        let container = listItem.appendChild(document.createElement('div'));
                        container.classList.add('flex');
                        let listItemSpan = container.appendChild(document.createElement('span'));
                        listItemSpan.style.backgroundColor = datasets[0].backgroundColor[index];
                        if (labels[index]) {
                            let innerContainer = container.appendChild(document.createElement('div'));
                            innerContainer.appendChild(document.createTextNode(labels[index]));
                            let content = chartSettings.legendText[labels[index]];
                            if (content) {
                                let btn = document.createElement('div');
                                btn.dataset.open = '+';
                                btn.dataset.close = '-';
                                btn.classList.add('chart-legend-btn');
                                listItem.appendChild(btn);
                                let text = document.createElement('p');
                                text.classList.add('content');
                                text.style.backgroundColor = datasets[0].backgroundColor[index];
                                text.innerHTML = chartSettings.legendText[labels[index]];
                                innerContainer.appendChild(text);
                                btn.onclick = () => {
                                    text.classList.toggle("active");
                                    btn.classList.toggle("active");
                                }
                            }
                        }
                        container.onclick = () => {
                            listItem.classList.toggle("disabled");
                            chart.toggleDataVisibility(item.index);
                            let newValue = 0;
                            chart.data.datasets[0].data.forEach((value, i) => {
                                if (!chart._hiddenIndices[i]) {
                                    newValue += value;
                                }
                            });
                            chartSettings.doughnutNumberValue = newValue;
                            chart.update();
                        };
                        list.appendChild(listItem);
                    }
                    element.parentNode.after(list);
                }
                element.classList.add('loaded');
                // all charts into array for custom function access
                charts.push({
                    'chart': chart,
                    'settings': chartSettings
                });
            }
        });
    };
});
