import { Component, OnInit } from "@angular/core";
import { AccountService } from "src/app/shared/server-services/account.service";
import { MeRecord, UserRole } from "src/app/shared/server-services/query-records/account-records";
import { aggregateStats, nanoMetricsQuery } from "src/app/shared/server-services/querys";
import { ServerRestApiService } from "src/app/shared/services/server-rest-api.service";

export type AggregateStatsRecord = {
  accounts: number;
  accountsUpdated: number;
  nanoMetricsUpdated: number;
  nanoMetrics: {
    year: number;
    month: number;
    requestBytes: number;
    responseBytes: number;
    cacheBytes: number;
    requestColumnHeight: number;
    responseColumnHeight: number;
    cacheColumnHeight: number;
    sumColumnHeight: number;
  }[];
};

export type StatsRecord = {  
  year: number;
  month: number;
  /**
   * Msg to the nano
   * nano download
   * client upload
   */
  requestBytes: number;
  /**
   * Nano response
   * nano upload
   * client download
   */
  responseBytes: number;
  /**
   * Server response instead of nano (file)
   * nano do nothing
   * client download
   */
  cacheBytes: number;
  requestColumnHeight: number;
  responseColumnHeight: number;
  cacheColumnHeight: number;
  sumColumnHeight: number;
}

// export type AggregateStats = {
//   accounts: number;
//   accountsUpdated: number;
//   nanoMetricsUpdated: number;
//   nanoMetrics: {
//     year: number;
//     month: number;
//     requestBytes: number;
//     responseBytes: number;
//     cacheBytes: number;
//   }[];
// }

@Component({
  selector: "app-aggregate-stats",
  templateUrl: "./aggregate-stats.component.html",
  styleUrls: ["./aggregate-stats.component.scss"],
})
export class AggregateStatsComponent implements OnInit {
  
  public adminStats: AggregateStatsRecord;
  public stats: StatsRecord[];

  public isAdmin: boolean = false;
  public loadingData: boolean = true;
  public showAggregateStats: boolean = false;
  
  constructor(private serverRestApiService: ServerRestApiService, private accountService: AccountService) {

    Promise.all(
      [this.accountService.getMe(), 
        this.getMetrics()])
      .then(([me, metrics]) => {

        this.isAdmin = this.accountService.isCurrentUserInRole(UserRole.ADMIN, me);

        this.stats = metrics;
        this.processMetrics(metrics);

        this.loadingData = false;
      });
  }

  ngOnInit(): void {}

  public displayAggregateStats(show: boolean): void{

    if(show && !this.adminStats){
      this.loadingData = true;
      this.serverRestApiService
      .query({
        query: aggregateStats,
      })
      .then((response: AggregateStatsRecord) => {
        this.adminStats = response;

        this.processMetrics(this.adminStats.nanoMetrics);
        this.showAggregateStats = true;
        this.loadingData = false;
      });
    }
    else{
      this.showAggregateStats = show;
    }
  }

  private processMetrics(metrics: StatsRecord[]): void{
    metrics.sort((a, b) => {
      if(a.year == b.year)
        return b.month - a.month;
      else
        return b.year - a.year;
    });

    var maxUpload = Math.max(...metrics.map(m => m.responseBytes + m.cacheBytes), ...metrics.map(m => m.requestBytes));

    for(let stat of metrics){
      var maxOnePercent = maxUpload / 100;
      stat.requestColumnHeight = Math.max(Math.round(stat.requestBytes / maxOnePercent), .5);      
      stat.responseColumnHeight = Math.max(Math.round(stat.responseBytes / maxOnePercent), .5);
      stat.cacheColumnHeight = Math.max(Math.round(stat.cacheBytes / ((stat.responseBytes + stat.cacheBytes) / 100)), .5);
      stat.sumColumnHeight = Math.max(Math.round((stat.responseBytes + stat.cacheBytes) / maxOnePercent), .5);
    }
  }

  private getMetrics(): Promise<StatsRecord[]>{
    return  this.serverRestApiService.query({query: nanoMetricsQuery});
  }
}
