window.Graficos = window.Graficos || {}

Graficos.criarGrafico = ({
    container,
    tipo,
    dados,
    grafico3d = true,
    nomeSerie = 'Valor',
    colunasAgrupamento,
    colunasValor,
    title = null,
    colunasDescricao = [],
    formatarValor = (valor) => {
        return valor.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    },
    cores = {},
    bHorizontal = false,
    qtdeRegistros = 25,
    seriesAgrupadas = false,
    ordenacao = [],
    colunasSeries = []
}) => {
    if (Highcharts.charts && Highcharts.charts.length > 0) {
        const graficoExistente = Highcharts.charts.find(chart => chart?.renderTo.id === container);
        if (graficoExistente) {
            graficoExistente.destroy();
        }
    }

    const { categories, data } = Graficos.prepararDadosParaGrafico(dados, colunasAgrupamento, colunasValor, colunasDescricao, qtdeRegistros, seriesAgrupadas, ordenacao, colunasSeries);

    if (cores && Object.keys(cores).length > 0) {
        data.forEach((item) => {
            if (cores[item.name]) {
                item.color = cores[item.name];
            }
        });
    }

    function buscaBackgroundColor() {
        return $('body').css('--background-color') || $('body').css('background-color') || '#ffffff';
    }

    Highcharts.addEvent(Highcharts.Chart, 'fullscreenOpen', function () {
        this.update({
            chart: {
                backgroundColor: buscaBackgroundColor()
            }
        });
    });

    Highcharts.addEvent(Highcharts.Chart, 'fullscreenClose', function () {
        this.update({
            chart: {
                backgroundColor: null
            }
        });
    });


    Highcharts.chart(container, {
        credits: { enabled: false },
        exporting: {
            enabled: true,
            buttons: {
                contextButton: {
                    menuItems: [
                        "viewFullscreen",
                        "printChart",
                        "separator",
                        "downloadPNG",
                        "downloadJPEG",
                        "downloadPDF",
                        "downloadSVG",
                        // "separator",
                        // "downloadCSV",
                        // "downloadXLS"
                    ]
                }
            }
        },
        lang: {
            viewFullscreen: "Ver em tela cheia",
            printChart: "Imprimir gráfico",
            downloadPNG: "Baixar PNG",
            downloadJPEG: "Baixar JPEG",
            downloadPDF: "Baixar PDF",
            downloadSVG: "Baixar SVG",
            // downloadCSV: "Baixar CSV",
            // downloadXLS: "Baixar XLS",
            contextButtonTitle: "Opções de exportação"
        },
        navigation: {
            menuItemHoverStyle: {
                background: "var(--hover-color)"
            },
            buttonOptions: {
                theme: {
                    fill: "var(--color-secondary)"
                }
            },
            menuStyle: {
                background: "var(--color-secondary)"
            },
            menuItemStyle: {
                fontSize: "14px",
                fontWeight: "bold",
                color: "var(--font-color)"
            },
        },
        chart: {
            type: tipo,
            inverted: bHorizontal,
            options3d: grafico3d ? { enabled: true, alpha: tipo === 'pie' || tipo === 'donut' ? 45 : 15, beta: 0, depth: 50, viewDistance: 25 } : null,
            backgroundColor: null
        },
        title: {
            text: title,
            align: 'center',
            style: {
                color: 'var(--font-color)',
                fontSize: '18px',
                fontWeight: 'bold'
            }
        },
        xAxis: tipo === 'column' ? {
            categories: categories,
            labels: { style: { color: 'var(--font-color)', fontSize: '14px', fontWeight: 'bold' } }
        } : undefined,
        yAxis: tipo === 'column' ? {
            title: { text: null },
            labels: { formatter: function () { return formatarValor(this.value) }, style: { color: 'var(--font-color)' } }
        } : undefined,
        tooltip: {
            formatter: function () {
                if (tipo === 'pie' || tipo === 'donut') {
                    return `${this.options.name}: <b>${this.percentage.toFixed(0)}%</b>`;
                }
                return `${seriesAgrupadas ? this.series.name : nomeSerie}: <b>${formatarValor(this.y)}</b>`;
            },
        },
        plotOptions: {
            series: {
                allowPointSelect: true,
                cursor: 'pointer',
                borderWidth: 2,
                borderColor: 'var(--borda-grafico)',
                dataLabels: [
                    {
                        enabled: !seriesAgrupadas,
                        distance: 0,
                        rotation: false ? -75 : 0,
                        formatter: function () {
                            if (tipo == 'column') {
                                return formatarValor(this.y);
                            }
                            return `${this.name} - ${formatarValor(this.y)}`;
                        },
                        style: {
                            color: 'var(--font-color)',
                            fontSize: '14px',
                            fontWeight: 'bold',
                            textOutline: 'none',
                        },
                    },
                    {
                        enabled: false,
                        distance: -17.5,
                        format: '{point.percentage:.0f}%',
                        style: {
                            fontSize: '0.8rem',
                        },
                        filter: {
                            operator: '>',
                            property: 'percentage',
                            value: 5,
                        },
                    },
                ],
            },
            pie: tipo === 'pie' || tipo === 'donut' ? {
                size: '80%',
                allowPointSelect: true,
                cursor: 'pointer',
                dataLabels: { enabled: false },
                showInLegend: true,
                depth: grafico3d ? 45 : null,
            } : undefined,
        },
        legend: {
            enabled: seriesAgrupadas,
            useHTML: true,
            ...(!seriesAgrupadas && {
                labelFormatter: function () {
                    return `<span style="color:${this.color}">\u25A0</span> ${this.name}`;
                }
            }),
            ...(seriesAgrupadas && {
                itemStyle: {
                    color: 'var(--font-color)', // ou qualquer outra cor que você quiser
                    fontSize: '14px',
                    fontWeight: 'bold'
                }
            })
        },
        series:
            seriesAgrupadas
                ?

                Object.keys(data[0].y).map(coluna => ({
                    name: coluna,
                    type: tipo === 'donut' ? 'pie' : tipo,
                    data: data.map(item => item.y[coluna] || 0)
                }))

                :

                [
                    {
                        type: tipo === 'donut' ? 'pie' : tipo,
                        name: nomeSerie,
                        colorByPoint: true,
                        innerSize: tipo === 'donut' ? '70%' : undefined,
                        data,
                        showInLegend: tipo === 'pie' || tipo === 'donut',
                    }
                ]
    });
};


Graficos.prepararDadosParaGrafico = (dados, colunasAgrupamento, colunasValor, colunasDescricao, qtdeRegistros, seriesAgrupadas, ordenacao, colunasSeries) => {
    const agrupado = {}

    dados.forEach((item) => {
        let chave;
        let valor;

        if (colunasSeries.length > 0) {
            colunasSeries.forEach(colunaSerie => {
                colunasAgrupamento.forEach((colunaAgrupamento, index) => {
                    const chave = colunasDescricao.length > 0 ? (colunasDescricao[index] || colunaAgrupamento) : colunaAgrupamento;
                    const coluna = colunaSerie;

                    if (!agrupado[chave]) {
                        agrupado[chave] = {};
                    }

                    if (!agrupado[chave][item[coluna]]) {
                        agrupado[chave][item[coluna]] = 0;
                    }

                    agrupado[chave][item[coluna]] += item[colunasValor[index]] ? item[colunasValor[index]] : 0;
                });
            })
        } else if (colunasAgrupamento.length > 1) {
            colunasAgrupamento.forEach((coluna, index) => {
                const descricao = colunasDescricao.length > 0 ? (colunasDescricao[index] || coluna) : coluna;

                if (!agrupado[descricao]) {
                    agrupado[descricao] = 0;
                }

                agrupado[descricao] += item[colunasValor[index]] ? item[colunasValor[index]] : 0;
            });
        } else {
            chave = item[colunasAgrupamento] || 'Desconhecido';

            if (seriesAgrupadas) {
                colunasValor.forEach(coluna => {
                    valor = item[coluna] || 0;

                    if (!agrupado[chave]) {
                        agrupado[chave] = {};
                    }

                    if (!agrupado[chave][coluna]) {
                        agrupado[chave][coluna] = 0;
                    }

                    agrupado[chave][coluna] += valor;
                });
                return;
            }
            valor = item[colunasValor] || 0;

            const descricao = colunasDescricao.length > 0 ? (colunasDescricao[0] || chave) : chave;

            if (!agrupado[descricao]) {
                agrupado[descricao] = 0;
            }

            agrupado[descricao] += valor;
        }
    });

    const arr = Object.entries(agrupado);
    arr.sort((a, b) => b[1] - a[1]);
    if (ordenacao.length > 0) {
        arr.sort((a, b) => {
            return ordenacao.indexOf(a[0]) - ordenacao.indexOf(b[0]);
        });
    }
    const objOrdenado = arr.slice(0, qtdeRegistros).map(([name, y]) => ({ name, y }));
    const categorias = objOrdenado.map(item => item.name);
    const data = objOrdenado;

    return { categories: categorias, data }
}

Graficos.limpaGrafico = (container = []) => {
    if (Highcharts.charts && Highcharts.charts.length > 0) {
        container.forEach(item => {
            const graficoExistente = Highcharts.charts.find(chart => chart?.renderTo.id === item);
            if (graficoExistente) {
                graficoExistente.destroy();
            }
        })
    }
}


