import { Component, OnInit, ViewChild } from "@angular/core";
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
import { MatTabChangeEvent, MatTabGroup } from "@angular/material/tabs";
import { TranslateModule, TranslateService } from "@ngx-translate/core";
import { DatePipe } from "@angular/common";
import { ChartConfiguration, ChartData, ChartType } from "chart.js";
import { BaseChartDirective } from "ng2-charts";
import { MatTabsModule } from "@angular/material/tabs";
import { MatIconModule } from "@angular/material/icon";

import { ServiceComm } from "../../services/service-comm.service";
import { StatsService } from "../../services/stats.service";
import {
  StatsByDzResp,
  StatsByAircraftResp,
  StatsByGearResp,
  StatsByJumpTypeResp,
  StatsByYearResp,
} from "../../models/stats";

@Component({
  selector: "app-summary",
  templateUrl: "./summary.component.html",
  styleUrls: ["./summary.component.css"],
  imports: [
    MatTabsModule,
    TranslateModule,
    BaseChartDirective,
    MatIconModule,
    MatTableModule,
  ],
})
export class SummaryComponent implements OnInit {
  public dsNbJumpByDz: MatTableDataSource<StatsByDzResp>;
  public dsNbJumpByAircraft: MatTableDataSource<StatsByAircraftResp>;
  public dsNbJumpByGear: MatTableDataSource<StatsByGearResp>;
  public dsNbJumpByType: MatTableDataSource<StatsByJumpTypeResp>;
  public dsNbJumpByYear: MatTableDataSource<StatsByYearResp>;
  public dsJumpForLastYearByDz: MatTableDataSource<StatsByDzResp>;
  public dsJumpForLastYearByJumpType: MatTableDataSource<StatsByJumpTypeResp>;
  public dsJumpForLastMonthByDz: MatTableDataSource<StatsByDzResp>;
  public dsJumpForLastMonthByJumpType: MatTableDataSource<StatsByJumpTypeResp>;
  public displayedColumns: Array<string> = ["label", "nb"];
  public displayedColumnsByYearByJumpType: Array<string> = [
    "label",
    "label2",
    "nb",
  ];

  public barChartLegend = true;
  public barChartPlugins: any = [];
  public barChartData: ChartData<"line">;
  public barChartOptions: ChartConfiguration["options"];
  public barChartType: ChartType;
  private jumpTypeToColor: Map<string, string>;

  public totalJumps: number;
  public totalCutaways: number;
  public lastJump: string;
  @ViewChild(MatTabGroup) tabGroup: MatTabGroup;

  constructor(
    private serviceApi: StatsService,
    private serviceComm: ServiceComm,
    private translateService: TranslateService
  ) {}

  ngOnInit() {
    this.serviceComm.forceTranslateTitle.subscribe((data) => {
      if (data === true) {
        this.updateTitle();
      }
    });
    this.updateTitle();

    this.serviceApi.getSimpleSummary().subscribe((data) => {
      this.totalJumps = data.totalJumps;
      this.totalCutaways = data.totalCutaways;

      const datepipe: DatePipe = new DatePipe("en-US");
      let formattedDate = datepipe.transform(
        data.lastJump.jumpDate,
        "EEEE dd MMMM YYYY"
      );
      this.lastJump = formattedDate + " (" + data.lastJump.dropZone.name + ")";
    });

    this.serviceApi.getStatsOfLastMonth().subscribe((data) => {
      data.byDz.sort((a, b) => b.nb - a.nb);
      this.dsJumpForLastMonthByDz = new MatTableDataSource(data.byDz);
      data.byJumpType.sort((a, b) => b.nb - a.nb);
      this.dsJumpForLastMonthByJumpType = new MatTableDataSource(
        data.byJumpType
      );
    });

    this.chartConfig();
  }

  public refreshStats() {
    this.serviceApi.deleteAllCache();
    this.tabGroup.selectedIndex = 0;
  }

  public onTabChanged(event: MatTabChangeEvent) {
    switch (event.index) {
      case 0:
        this.serviceApi.getStatsOfLastMonth().subscribe((data) => {
          data.byDz.sort((a, b) => b.nb - a.nb);
          this.dsJumpForLastMonthByDz = new MatTableDataSource(data.byDz);
          data.byJumpType.sort((a, b) => b.nb - a.nb);
          this.dsJumpForLastMonthByJumpType = new MatTableDataSource(
            data.byJumpType
          );
        });
        break;
      case 1:
        this.serviceApi.getStatsOfLastYear().subscribe((data) => {
          data.byDz.sort((a, b) => b.nb - a.nb);
          this.dsJumpForLastYearByDz = new MatTableDataSource(data.byDz);
          data.byJumpType.sort((a, b) => b.nb - a.nb);
          this.dsJumpForLastYearByJumpType = new MatTableDataSource(
            data.byJumpType
          );
        });
        break;
      case 2:
        this.serviceApi.getStatsByDz().subscribe((data) => {
          data.sort((a, b) => b.nb - a.nb);
          this.dsNbJumpByDz = new MatTableDataSource(data);
        });
        break;
      case 3:
        this.serviceApi.getStatsByAircraft().subscribe((data) => {
          data.sort((a, b) => b.nb - a.nb);
          this.dsNbJumpByAircraft = new MatTableDataSource(data);
        });
        break;
      case 4:
        this.serviceApi.getStatsByGear().subscribe((data) => {
          data.sort((a, b) => b.nb - a.nb);
          this.dsNbJumpByGear = new MatTableDataSource(data);
        });
        break;
      case 5:
        this.serviceApi.getStatsByJumpType().subscribe((data) => {
          data.sort((a, b) => b.nb - a.nb);
          this.dsNbJumpByType = new MatTableDataSource(data);
        });
        break;
      case 6:
        this.serviceApi.getStatsByYear().subscribe((data) => {
          data.sort((a, b) => b.label.localeCompare(a.label));
          this.dsNbJumpByYear = new MatTableDataSource(data);
        });
        break;
      case 7:
        this.serviceApi.getStatsByYearByJumpType().subscribe((data) => {
          data.sort((a, b) => a.label.localeCompare(b.label));

          let firstYear: number = Number(data[0].label);
          const now = new Date();
          const currentYear = now.getFullYear();
          const nbYears = currentYear - firstYear;
          let listOfYears = new Array(nbYears)
            .fill(null)
            .map(() => firstYear++);

          // Prepare the list of jump type with am empty array
          let tmpResults = new Map<string, number[]>();
          const listOfJumpType = [...new Set(data.map((obj) => obj.label2))];
          listOfJumpType.forEach((type) => {
            tmpResults.set(type, new Array(nbYears).fill(NaN));
          });

          for (let i = 0; i < listOfYears.length; i++) {
            const year = listOfYears[i].toString();

            let filteredStats = data.filter((d) => d.label == year);

            if (filteredStats.length > 0) {
              filteredStats.forEach((fs) => {
                tmpResults.get(fs.label2)[i] = fs.nb;
              });
            }
          }

          const results: {
            label: string;
            data: number[];
            backgroundColor: string;
            borderColor: string;
            pointBackgroundColor: string;
            fill: boolean;
            pointRadius: number;
          }[] = [];
          tmpResults.forEach((value, key) => {
            const color = this.jumpTypeToColor.get(key);
            let tmp = {
              label: key,
              data: value,
              backgroundColor: color,
              borderColor: color,
              pointBackgroundColor: color,
              fill: false,
              pointRadius: 6,
            };
            results.push(tmp);
          });

          this.barChartData = {
            labels: listOfYears,
            datasets: results,
          };
        });
        break;
    }
  }

  private updateTitle() {
    this.translateService.get("Summary_Title").subscribe((data) => {
      this.serviceComm.updatedComponentTitle(data);
    });
  }

  private chartConfig() {
    this.barChartType = "line";
    this.barChartOptions = {
      responsive: true,
      maintainAspectRatio: false,
      plugins: {
        legend: {
          display: true,
        },
        colors: {
          forceOverride: true,
        },
      },
      interaction: {
        intersect: false,
        mode: "nearest",
        axis: "x",
      },
      scales: {
        x: {
          stacked: false,
        },
        y: {
          stacked: false,
          beginAtZero: true,
        },
      },
    };

    this.jumpTypeToColor = new Map<string, string>([
      ["PAC", "#FFD700"],
      ["Solo", "#FFA500"],
      ["RW 3", "#40E0D0"],
      ["RW 4", "#008080"],
      ["RW 8", "#7FFFD4"],
      ["RW X", "#114556"],
      ["FreeFly", "#FFC0CB"],
      ["FreeStyle", "#FF91A4"],
      ["Track/Trace", "#87CEEB"],
      ["Canopy", "#228B22"],
      ["Landing accuracy", "#FF6347"],
      ["Wingsuit 1", "#E6E6FA"],
      ["Wingsuit 2", "#E0B0FF"],
      ["Wingsuit 3", "#9400D3"],
    ]);
  }
}
