import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { DecimalPipe } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatDividerModule } from '@angular/material/divider';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { Observable, Subscription } from 'rxjs';

import { MenuItems } from '@components/shared';
import { BarsChartComponent } from '@components/shared/helpers-chart';
import { UtilitiesService, JumpsService } from '@services';
import { JumpByDate } from '@models';

@Component({
    selector: 'app-jumps-by-month',
    imports: [
        DecimalPipe,
        MatButtonModule,
        MatCardModule,
        MatDividerModule,
        MatExpansionModule,
        MatIconModule,
        MatMenuModule,
        BarsChartComponent,
    ],
    templateUrl: './jumps-by-month.component.html',
})
export class JumpsByMonthComponent implements OnInit, OnDestroy {
    private _jumpsService = inject(JumpsService);
    private _utilitiesService = inject(UtilitiesService);
    menuItems = inject(MenuItems);

    private _jumpByDate: Subscription = new Subscription();
    private _jumpsByDate!: Array<JumpByDate>;
    private _jumpsByDateCount = 0;
    public title: string = 'Volume mensuel';
    public subtitle: string = 'Nombre total de sauts par mois';
    public min = 0;
    public max = 0;
    public grandAvg = 0;
    public grandAvgLastYears = 0;
    public grandTotal = 0;
    public seriesHeader: string[] = [];
    public seriesName: string[] = [];
    public seriesRow: Array<Array<number>> = [];
    public seriesColor: {
        backgroundColor: string[];
        borderColor: string[];
    } = {
        backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'),
        borderColor: this._utilitiesService.getSeriesColors(1, 'all'),
    };
    public seriesColorClass: string[] = this._utilitiesService.getChartColors();
    public seriesRowTotal: number[] = [];
    public seriesRowAvg: number[] = [];
    public seriesRowAvgLastYears: number[] = [];
    public seriesColTotal: number[] = [];
    public seriesColTotalClosed: number[] = [];
    public seriesColTotalLastYears: number[] = [];
    public displayCharts = false;
    public destroyRef = inject(DestroyRef);

    ngOnInit() {
        this._loadJumpByDate();
    }

    ngOnDestroy() {
        this._jumpByDate.unsubscribe();
    }

    private _loadJumpByDate() {
        const minoration = 2; // -2 pour ne pas compter la première année
        this.seriesHeader = this._utilitiesService.getMonthsList();
        const values: Array<number> = this.seriesHeader.map(() => 0);
        this.seriesColTotal = [...values];
        this.seriesColTotalClosed = [...values];
        this.seriesColTotalLastYears = [...values];
        const jumps$: Observable<Array<JumpByDate>> = this._jumpsService
            .getAllByDate()
            .pipe(takeUntilDestroyed(this.destroyRef));
        this._jumpByDate = jumps$.subscribe((aggregate: Array<JumpByDate>) => {
            this._jumpsByDateCount = aggregate.length;
            this._jumpsByDate = aggregate.map((row: JumpByDate) => {
                const currentYear: number = new Date().getFullYear();
                const year = row.year.toString();
                const month = row.month;
                if (this.seriesName.indexOf(year) < 0) {
                    this.seriesName.push(year);
                    if (row.year < this.min || this.min == 0) {
                        this.min = row.year;
                    }
                    if (row.year > this.max) {
                        this.max = row.year;
                    }
                    this.seriesRow.push([...values]);
                }
                this.seriesRow[this.seriesRow.length - 1][month - 1] = row.count;
                this.seriesColTotal[month - 1] += row.count;
                if (row.year < currentYear) {
                    this.seriesColTotalClosed[month - 1] += row.count;
                }
                if (row.year >= currentYear - 3 && row.year < currentYear) {
                    this.seriesColTotalLastYears[month - 1] += row.count;
                }
                return row;
            });
            this.seriesRow.forEach((row: number[]) => {
                const total = row.reduce((partialSum, a) => partialSum + a, 0);
                this.seriesRowTotal.push(total);
            });
            this.seriesColTotalClosed.forEach((row: number) => {
                const value: number = row / (this.seriesName.length - minoration);
                this.seriesRowAvg.push(parseInt(value.toFixed(0)));
            });
            this.seriesColTotalLastYears.forEach((row: number) => {
                const value: number = row / 3; // Les 3 dernières années
                this.seriesRowAvgLastYears.push(parseInt(value.toFixed(0)));
            });
            this.grandAvg = this.seriesRowAvg.reduce((partialSum, accumulated) => partialSum + accumulated, 0);
            this.grandAvgLastYears = this.seriesRowAvgLastYears.reduce(
                (partialSum, accumulated) => partialSum + accumulated,
                0,
            );
            this.grandTotal = this.seriesColTotal.reduce((partialSum, accumulated) => partialSum + accumulated, 0);
            this.displayCharts = true;
        });
    }
}
