import { Injectable } from '@angular/core';
import { Chart } from 'chart.js';

import { BarConfig, CircleConfig, DoughnutConfig, LineConfig } from '@models';

@Injectable({ providedIn: 'root' })
export class UtilitiesService {
    private _coeffKgLbs: number = 2.20462;
    private _coeffFtM: number = 0.092903;

    constructor() {}

    getCoeffKgLbs(): number {
        return this._coeffKgLbs;
    }

    getCoeffFtM(): number {
        return this._coeffFtM;
    }

    getChartColors(): string[] {
        const colors: string[] = [
            'ct-color-a',
            'ct-color-b',
            'ct-color-c',
            'ct-color-d',
            'ct-color-e',
            'ct-color-f',
            'ct-color-g',
            'ct-color-h',
            'ct-color-i',
            'ct-color-j',
            'ct-color-k',
            'ct-color-l',
            'ct-color-m',
            'ct-color-n',
            'ct-color-o',
            'ct-color-p',
            'ct-color-q',
            'ct-color-r',
            'ct-color-s',
            'ct-color-t',
            'ct-color-u',
            'ct-color-v',
            'ct-color-w',
            'ct-color-x',
            'ct-color-y',
            'ct-color-z',
        ];
        return colors;
    }

    getCurrentDateFr(): string {
        return new Date().toLocaleDateString('fr');
    }

    secondsToDuration(seconds: number, delimiter: string = ':'): string {
        return [Math.floor(seconds / 60 / 60), Math.floor((seconds / 60) % 60), Math.floor(seconds % 60)]
            .join(delimiter)
            .replace(/\b(\d)\b/g, '0$1'); //.replace(/^00\:/, '')
    }

    getSeriesColors(opacity: number, palette: string = 'all', offset: number = 0): string[] {
        let colors: string[] = [];
        switch (palette) {
            case 'pastels':
                colors = [
                    `rgba(171, 222, 230, ${opacity})`,
                    `rgba(203, 170, 203, ${opacity})`,
                    `rgba(255, 255, 181, ${opacity})`,
                    `rgba(255, 204, 182, ${opacity})`,
                    `rgba(243, 176, 195, ${opacity})`,
                    `rgba(198, 219, 218, ${opacity})`,
                    `rgba(254, 225, 232, ${opacity})`,
                    `rgba(254, 215, 195, ${opacity})`,
                    `rgba(246, 234, 194, ${opacity})`,
                    `rgba(236, 213, 227, ${opacity})`,
                    `rgba(255, 150, 138, ${opacity})`,
                    `rgba(255, 174, 165, ${opacity})`,
                    `rgba(255, 197, 191, ${opacity})`,
                    `rgba(255, 216, 190, ${opacity})`,
                    `rgba(255, 200, 162, ${opacity})`,
                    `rgba(212, 240, 240, ${opacity})`,
                    `rgba(143, 202, 202, ${opacity})`,
                    `rgba(204, 226, 203, ${opacity})`,
                    `rgba(182, 207, 182, ${opacity})`,
                    `rgba(151, 193, 169, ${opacity})`,
                ];
                break;
            case 'red':
                colors = [
                    `rgba(163, 0, 0, ${opacity})`,
                    `rgba(178, 47, 25, ${opacity})`,
                    `rgba(192, 74, 49, ${opacity})`,
                    `rgba(205, 99, 72, ${opacity})`,
                    `rgba(217, 122, 97, ${opacity})`,
                    `rgba(228, 145, 122, ${opacity})`,
                    `rgba(238, 168, 148, ${opacity})`,
                    `rgba(247, 192, 175, ${opacity})`,
                    `rgba(255, 215, 203, ${opacity})`,
                ];
                break;
            case 'green':
                colors = [
                    `rgba(0, 109, 45, ${opacity})`,
                    `rgba(42, 124, 64, ${opacity})`,
                    `rgba(67, 140, 83, ${opacity})`,
                    `rgba(90, 155, 102, ${opacity})`,
                    `rgba(112, 171, 122, ${opacity})`,
                    `rgba(134, 187, 142, ${opacity})`,
                    `rgba(156, 203, 163, ${opacity})`,
                    `rgba(179, 219, 184, ${opacity})`,
                    `rgba(201, 235, 205, ${opacity})`,
                ];
                break;
            case 'blue':
                colors = [
                    `rgba(0, 76, 109, ${opacity})`,
                    `rgba(37, 94, 126, ${opacity})`,
                    `rgba(61, 112, 143, ${opacity})`,
                    `rgba(83, 131, 161, ${opacity})`,
                    `rgba(105, 150, 179, ${opacity})`,
                    `rgba(127, 170, 198, ${opacity})`,
                    `rgba(148, 190, 217, ${opacity})`,
                    `rgba(171, 210, 236, ${opacity})`,
                    `rgba(193, 231, 255, ${opacity})`,
                ];
                break;
            case 'all':
            default:
                colors = [
                    `rgba(53, 162, 235, ${opacity})`,
                    `rgba(255, 99, 132, ${opacity})`,
                    `rgba(75, 192, 192, ${opacity})`,
                    `rgba(255, 159, 64, ${opacity})`,
                    `rgba(153, 102, 255, ${opacity})`,
                    `rgba(255, 205, 86, ${opacity})`,
                    `rgba(201, 203, 207, ${opacity})`,
                    `rgba(93, 204, 137, ${opacity})`,
                    `rgba(181, 17, 86, ${opacity})`,
                    `rgba(255, 226, 5, ${opacity})`,
                    `rgba(191, 101, 224, ${opacity})`,
                    `rgba(76, 174, 76, ${opacity})`,
                    `rgba(237, 80, 148, ${opacity})`,
                    `rgba(51, 122, 183, ${opacity})`,
                    `rgba(253, 24, 243, ${opacity})`,
                    `rgba(214, 31, 31, ${opacity})`,
                    `rgba(0, 137, 123, ${opacity})`,
                    `rgba(153, 171, 180, ${opacity})`,
                    `rgba(205, 186, 152, ${opacity})`,
                    `rgba(101, 224, 184, ${opacity})`,
                    `rgba(2, 191, 171, ${opacity})`,
                    `rgba(101, 218, 224, ${opacity})`,
                    `rgba(161, 199, 161, ${opacity})`,
                    `rgba(217, 202, 174, ${opacity})`,
                    `rgba(151, 136, 199, ${opacity})`,
                    `rgba(212, 206, 112, ${opacity})`,
                    `rgba(32, 182, 252, ${opacity})`,
                    `rgba(241, 80, 80, ${opacity})`,
                    `rgba(2, 191, 171, ${opacity})`,
                    `rgba(255, 153, 0, ${opacity})`,
                    `rgba(101, 218, 224, ${opacity})`,
                    `rgba(138, 101, 224, ${opacity})`,
                    `rgba(0, 137, 123, ${opacity})`,
                    `rgba(181, 17, 86, ${opacity})`,
                    `rgba(93, 204, 137, ${opacity})`,
                    `rgba(255, 226, 5, ${opacity})`,
                    `rgba(191, 101, 224, ${opacity})`,
                    `rgba(76, 174, 76, ${opacity})`,
                    `rgba(51, 122, 183, ${opacity})`,
                    `rgba(237, 80, 148, ${opacity})`,
                    `rgba(253, 24, 243, ${opacity})`,
                    `rgba(214, 31, 31, ${opacity})`,
                    `rgba(153, 171, 180, ${opacity})`,
                    `rgba(205, 186, 152, ${opacity})`,
                    `rgba(101, 224, 184, ${opacity})`,
                    `rgba(2, 191, 171, ${opacity})`,
                    `rgba(101, 218, 224, ${opacity})`,
                    `rgba(161, 199, 161, ${opacity})`,
                    `rgba(217, 202, 174, ${opacity})`,
                    `rgba(151, 136, 199, ${opacity})`,
                    `rgba(212, 206, 112, ${opacity})`,
                    `rgba(255, 255, 255, ${opacity})`,
                ];
                if (offset > 0 && offset < colors.length) {
                    colors = colors.slice(offset);
                }
                break;
        }
        return colors;
    }

    getCircleChartConfig(): CircleConfig {
        const config: CircleConfig = {
            circleChartLabels: [],
            circleChartDatasets: [
                {
                    data: [],
                    label: 'Nombre total de sauts',
                    backgroundColor: this.getSeriesColors(0.8),
                    borderColor: this.getSeriesColors(1), // 'rgba(255, 255, 255, 1)'
                    borderWidth: 2,
                },
            ],
            circleChartOptions: {
                cutout: '90%',
                elements: {
                    arc: {
                        //spacing: -10,
                        borderJoinStyle: 'round',
                        borderRadius: 10,
                        borderWidth: 0,
                    },
                },
                plugins: {
                    legend: {
                        display: false,
                        position: 'left',
                    },
                },
                responsive: true,
                maintainAspectRatio: false,
                animation: {
                    onProgress: function (this: Chart) {
                        const width = this.width,
                            height = this.height,
                            ctx = this.ctx;
                        const count: number = parseInt(this.data.datasets[0].data[0]!.toString());
                        const diff: number = parseInt(this.data.datasets[0].data[1]!.toString());
                        const total: number = count + diff;
                        const percent: number = Math.round((count / total) * 100);
                        const lineHeight = height / 8;
                        ctx.restore();
                        let fontSize = (height / 120).toFixed(2);
                        ctx.font = `${fontSize}em sans-serif`;
                        //ctx.textAlign = 'center';
                        ctx.textBaseline = 'middle';
                        ctx.fillStyle = '#dddddd';
                        //const text = `${percent} % (${count} ${this.data.datasets[0].label})`, textX = Math.round((width - ctx.measureText(text).width) / 2), textY = height / 2;
                        let text = this.data.datasets[0].label!;
                        let textX = Math.round((width - ctx.measureText(text).width) / 2);
                        let textY = height / 2;
                        ctx.fillText(text, textX, textY - lineHeight);
                        text = `${percent}%`;
                        textX = Math.round((width - ctx.measureText(text).width) / 2);
                        textY = height / 2;
                        ctx.fillText(text, textX, textY);

                        ctx.restore();
                        fontSize = (height / 180).toFixed(2);
                        ctx.font = `${fontSize}em sans-serif`;
                        ctx.textBaseline = 'middle';
                        ctx.fillStyle = '#dddddd';
                        text = `${count} / ${total}`;
                        textX = Math.round((width - ctx.measureText(text).width) / 2);
                        textY = height / 2;
                        ctx.fillText(text, textX, textY + lineHeight);
                        ctx.save();
                        //console.log(width, height, fontSize);
                    },
                    onComplete: function (this: Chart) {
                        const width = this.width,
                            height = this.height,
                            ctx = this.ctx;
                        const count: number = parseInt(this.data.datasets[0].data[0]!.toString());
                        const diff: number = parseInt(this.data.datasets[0].data[1]!.toString());
                        const total: number = count + diff;
                        const percent: number = Math.round((count / total) * 100);
                        const lineHeight = height / 8;
                        ctx.restore();
                        let fontSize = (height / 120).toFixed(2);
                        ctx.font = `${fontSize}em sans-serif`;
                        //ctx.textAlign = 'center';
                        ctx.textBaseline = 'middle';
                        ctx.fillStyle = '#dddddd';
                        //ctx.fillStyle = this.data!.datasets[0].backgroundColor ? this.data.datasets[0].backgroundColor[0]!.toString() : '#dddddd';
                        //const text = `${percent} % (${count} ${this.data.datasets[0].label})`, textX = Math.round((width - ctx.measureText(text).width) / 2), textY = height / 2;
                        let text = this.data.datasets[0].label!;
                        let textX = Math.round((width - ctx.measureText(text).width) / 2);
                        let textY = height / 2;
                        ctx.fillText(text, textX, textY - lineHeight);
                        text = `${percent}%`;
                        textX = Math.round((width - ctx.measureText(text).width) / 2);
                        textY = height / 2;
                        ctx.fillText(text, textX, textY);

                        ctx.restore();
                        fontSize = (height / 180).toFixed(2);
                        ctx.font = `${fontSize}em sans-serif`;
                        ctx.textBaseline = 'middle';
                        ctx.fillStyle = '#dddddd';
                        text = `${count} / ${total}`;
                        textX = Math.round((width - ctx.measureText(text).width) / 2);
                        textY = height / 2;
                        ctx.fillText(text, textX, textY + lineHeight);
                        ctx.save();
                        //console.log(width, height, fontSize);
                    },
                },
            },
            circleChartPlugins: [
                /*{
                    beforeInit: (chart: Chart<"doughnut", number[], unknown>) => {
                        const dataset = chart.data.datasets[0];
                        chart.data.labels = [dataset.label];
                        dataset.data = [dataset.data[0], 100 - dataset.data[0]];
                    },
                    id: 'beforeinit'
                },*/
                {
                    beforeDatasetDraw: (chart: Chart<'doughnut', number[], unknown>) => {
                        const width = chart.width,
                            height = chart.height,
                            ctx = chart.ctx;
                        ctx.restore();
                        const fontSize = (height / 150).toFixed(2);
                        ctx.font = fontSize + 'em sans-serif';
                        ctx.fillStyle = '#ffffff';
                        ctx.textBaseline = 'middle';
                        const text = chart.data.datasets[0].data[0] + '%',
                            textX = Math.round((width - ctx.measureText(text).width) / 2),
                            textY = height / 2;
                        ctx.fillText(text, textX, textY);
                        ctx.save();
                        console.log(width, height, fontSize);
                    },
                    id: 'doughnutlabel',
                },
            ],
            circleChartLegend: false,
        };
        return config;
    }

    getDoughnutChartConfig(): DoughnutConfig {
        const config: DoughnutConfig = {
            doughnutChartLabels: [],
            doughnutChartDatasets: [
                {
                    data: [],
                    label: 'Nombre total de sauts',
                    backgroundColor: this.getSeriesColors(0.8),
                    borderColor: this.getSeriesColors(1), // 'rgba(255, 255, 255, 1)'
                    borderWidth: 2,
                },
            ],
            doughnutChartOptions: {
                elements: {
                    arc: {
                        borderWidth: 2,
                    },
                },
                plugins: {
                    legend: {
                        display: true,
                        position: 'left',
                    },
                },
                responsive: true,
                maintainAspectRatio: false,
            },
            doughnutChartLegend: false,
        };
        return config;
    }

    getBarChartConfig(): BarConfig {
        const config: BarConfig = {
            barChartData: {
                labels: [''],
                datasets: [],
            },
            barChartOptions: {
                plugins: {
                    legend: {
                        display: true,
                        position: 'top',
                    },
                },
                elements: {
                    bar: {
                        borderWidth: 1,
                    },
                },
                /*interaction: {
                    intersect: false,
                    axis: 'x'
                },*/
                scales: {
                    x: {
                        display: false,
                        beginAtZero: true,
                        ticks: { color: 'rgba(255,255,255,0.3)' },
                        grid: {
                            display: true,
                            color: 'rgba(255,255,255,0.1)',
                            tickBorderDash: [1, 2],
                            tickBorderDashOffset: 2,
                        },
                    },
                    y: {
                        display: true,
                        beginAtZero: true,
                        ticks: { color: 'rgba(255,255,255,0.3)' },
                        grid: {
                            display: true,
                            color: 'rgba(255,255,255,0.2)',
                            tickBorderDash: [1, 2],
                            tickBorderDashOffset: 2,
                        },
                    },
                },
                responsive: true,
                maintainAspectRatio: false,
            },
            barChartPlugins: [],
            barChartLegend: true,
        };
        return config;
    }

    getHorizontalBarChartConfig(): BarConfig {
        const config: BarConfig = {
            barChartData: {
                labels: [''],
                datasets: [],
            },
            barChartOptions: {
                indexAxis: 'y',
                elements: {
                    bar: {
                        borderWidth: 1,
                    },
                },
                plugins: {
                    legend: {
                        display: true,
                        position: 'left',
                    },
                    title: {
                        display: false,
                        text: 'Nombre total de sauts',
                    },
                },
                responsive: true,
                aspectRatio: 3,
                scales: {
                    x: {
                        beginAtZero: true,
                        ticks: { color: 'rgba(255,255,255,0.3)' },
                        grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1, 2] },
                    },
                    y: {
                        beginAtZero: true,
                        ticks: { color: 'rgba(255,255,255,0.3)' },
                        grid: { display: false, color: 'rgba(255,255,255,0.2)' },
                    },
                },
            },
            barChartPlugins: [],
            barChartLegend: false,
        };
        return config;
    }

    getLineChartConfig(): LineConfig {
        const config: LineConfig = {
            lineChartData: {
                labels: [],
                datasets: [],
            },
            lineChartOptions: {
                plugins: {
                    legend: {
                        display: true,
                        position: 'top',
                    },
                },
                /*interaction: {
                    intersect: false,
                    axis: 'x'
                },*/
                scales: {
                    x: {
                        display: true,
                        beginAtZero: true,
                        ticks: { color: 'rgba(255,255,255,0.3)' },
                        grid: {
                            display: true,
                            color: 'rgba(255,255,255,0.1)',
                            tickBorderDash: [1, 2],
                            tickBorderDashOffset: 2,
                        },
                    },
                    y: {
                        display: true,
                        beginAtZero: true,
                        ticks: { color: 'rgba(255,255,255,0.3)' },
                        grid: {
                            display: true,
                            color: 'rgba(255,255,255,0.2)',
                            tickBorderDash: [1, 2],
                            tickBorderDashOffset: 2,
                        },
                    },
                },
                responsive: true,
                maintainAspectRatio: false,
            },
            lineChartLegend: true,
        };
        return config;
    }

    getMonthsList(): Array<string> {
        return [
            'Janvier',
            'Février',
            'Mars',
            'Avril',
            'Mai',
            'Juin',
            'Juillet',
            'Août',
            'Septembre',
            'Octobre',
            'Novembre',
            'Décembre',
        ];
    }

    getStackedLineAreaChartConfig(): LineConfig {
        const config: LineConfig = {
            lineChartData: {
                labels: [],
                datasets: [],
            },
            lineChartOptions: {
                plugins: {
                    legend: {
                        display: true,
                        position: 'top',
                    },
                },
                interaction: {
                    mode: 'nearest',
                    axis: 'x',
                    intersect: false,
                },
                scales: {
                    x: {
                        display: true,
                        beginAtZero: true,
                        ticks: { color: 'rgba(255,255,255,0.3)' },
                        grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1, 2] },
                    },
                    y: {
                        display: true,
                        beginAtZero: true,
                        stacked: true,
                        ticks: { color: 'rgba(255,255,255,0.3)' },
                        grid: { display: true, color: 'rgba(255,255,255,0.2)', tickBorderDash: [1, 2] },
                    },
                },
                responsive: true,
                maintainAspectRatio: false,
            },
            lineChartLegend: true,
        };
        return config;
    }
}
