import { ChangeDetectorRef, Component, NgZone, OnDestroy, OnInit } from '@angular/core';
import { AuthService } from '@shared/auth/auth.service';
import { AppLocalStorageService } from '@shared/ui-api/app-local-storage.service';
import { RefreshTimer } from '@shared/ui-api/helpers/refresh-timer';
import {
  LicenseWarningDialogComponent
} from '@shared/common-dialogs/license/license-warning-dialog/license-warning-dialog.component';
import { MatDialog } from '@angular/material/dialog';
import { ConfigService } from '@shared/config/config.service';

@Component({
  selector: 'app-license-warning',
  templateUrl: './license-warning.component.html',
  styleUrls: ['./license-warning.component.scss']
})
export class LicenseWarningComponent implements OnInit, OnDestroy {
  opened = false;
  showWarn = false;
  licenseExpiringText: string;
  licenseDaysLeft: number;
  warningLevel: number;
  coreDaysLeft: number;
  maxCores: number;
  coresInUse: number;
  ramDaysLeft: number;
  maxRam: number;
  ramInUse: number;
  coresExceededText = $localize`You are using more CPU cores than your license allows.`;
  ramExceededText = $localize`You are using more ram than your license allows.`;
  warningText: string;
  intervalDisplayWarning = null as null | RefreshTimer;
  millisecondInterval = 3600 * 1000; // 1 hour
  maxClients: number;
  clientsInUse: number;
  clientsExpiring: boolean;
  private showCoresWarning: boolean;
  private showRamWarning: boolean;

  constructor(public authService: AuthService, private appLocalStorageService: AppLocalStorageService,
              private readonly matDialog: MatDialog, private configService: ConfigService,
              private ngZone: NgZone, private changeDetectorRef: ChangeDetectorRef,) {
  }

  handleWarning() {
    if (this.opened === false) {
      this.opened = true;
      this.matDialog.open(
        LicenseWarningDialogComponent, {
          data: {
            licenseDaysLeft: this.licenseDaysLeft,
            showCoresWarning: this.showCoresWarning,
            coreDaysLeft: this.coreDaysLeft,
            maxCores: this.maxCores,
            coresInUse: this.coresInUse,
            showRamWarning: this.showRamWarning,
            ramDaysLeft: this.ramDaysLeft,
            maxRam: this.maxRam,
            ramInUse: this.ramInUse,
            clientsExpiring: this.clientsExpiring,
            maxClients: this.maxClients,
            clientsInUse: this.clientsInUse,
          },
          autoFocus: false,
        }).afterClosed().subscribe(() => {
        this.opened = false;
      });
    }
  }

  displayWarning() {
    if (this.appLocalStorageService.getLicenseWarningHide() === true) {
      if (this.intervalDisplayWarning) {
        this.intervalDisplayWarning.stop();
        this.intervalDisplayWarning = null;
      }
    } else {
      this.appLocalStorageService.setLicenseLastWarningTime();
      this.handleWarning();
    }
  }

  displayWarningAndInitTimer() {
    this.displayWarning();
    if (this.intervalDisplayWarning) {
      // we need to stop old timer because it may have been shorter than millisecondInterval
      // (e.g. due to refreshing browser and having to re-init faster)
      this.intervalDisplayWarning.stop();
      this.intervalDisplayWarning = null;
    }
    this.intervalDisplayWarning = new RefreshTimer(this.millisecondInterval, () => {
      this.displayWarning();
    }, this.configService, this.ngZone, this.changeDetectorRef, true);
  };

  ngOnInit(): void {
    this.authService.observableUserData.subscribe(() => {
      this.initWarningData();
    });
  }

  initWarningData() {
    if (this.authService.userData && this.authService.userData.user) {
      if (this.authService.userData.user.license_expiring || this.authService.userData.user.cores_exceeded ||
        this.authService.userData.user.ram_exceeded || this.authService.userData.user.clients_expiring
      ) {
        this.showWarn = true;

        if (this.authService.userData.user.license_expiring) {
          this.licenseDaysLeft = this.authService.userData.user.license_expiring.warning_days;
          this.warningLevel = this.authService.userData.user.license_expiring.warning_level;
          if (this.licenseDaysLeft === 1) {
            this.licenseExpiringText = $localize`You have one day left from your license.`;
          } else {
            if (this.licenseDaysLeft < 0) {
              if (this.licenseDaysLeft === -1) {
                this.licenseExpiringText = $localize`License expired yesterday.`;
              } else {
                this.licenseExpiringText = $localize`License expired ${-this.licenseDaysLeft} days ago.`;
              }
            } else {
              this.licenseExpiringText = $localize`You have ${this.licenseDaysLeft} days left from your license.`;
            }
          }
        }

        this.warningText = this.licenseExpiringText || '';

        this.showCoresWarning = !!this.authService.userData.user.cores_exceeded;
        if (this.authService.userData.user.cores_exceeded) {
          this.coreDaysLeft = this.authService.userData.user.cores_exceeded.grace_days;
          this.maxCores = this.authService.userData.user.cores_exceeded.max_cores;
          this.coresInUse = this.authService.userData.user.cores_exceeded.cores_in_use;
          if (this.warningText) {
            this.warningText += '\n';
          }
          this.warningText += this.coresExceededText;
        }

        this.showRamWarning = !!this.authService.userData.user.ram_exceeded;
        if (this.authService.userData.user.ram_exceeded) {
          this.ramDaysLeft = this.authService.userData.user.ram_exceeded.grace_days;
          this.maxRam = this.authService.userData.user.ram_exceeded.max_ram;
          this.ramInUse = this.authService.userData.user.ram_exceeded.ram_in_use;
          if (this.warningText) {
            this.warningText += '\n';
          }
          this.warningText += this.ramExceededText;
        }

        if (this.authService.userData.user.clients_expiring) {
          this.clientsExpiring = true;
          this.maxClients = this.authService.userData.user.clients_expiring.max_clients;
          this.clientsInUse = this.authService.userData.user.clients_expiring.clients_in_use;
          this.warningLevel = this.authService.userData.user.clients_expiring.warning_level;
          if (this.warningText) {
            this.warningText += '\n';
          }
          this.warningText += $localize`You are using ${this.clientsInUse} clients of your total ${this.maxClients} clients.`;
        }

        // popup warning dialog hourly
        if (this.warningLevel === 2 &&
          this.appLocalStorageService.getLicenseWarningHide() === false) {
          const lastWarning = this.appLocalStorageService.getLicenseLastWarningTime();
          if (lastWarning !== null) {
            // if interval was killed (browser refresh or closed tab)
            if (this.intervalDisplayWarning === null) {
              // @ts-ignore
              if (new Date() - new Date(lastWarning) > this.millisecondInterval) {
                // hidden time passed, show dialog and init timer
                this.displayWarningAndInitTimer();
              } else {
                // display warning and init timer only after the "hidden" millisecond interval finishes
                this.intervalDisplayWarning = new RefreshTimer(
                  // @ts-ignore
                  this.millisecondInterval - (new Date() - new Date(lastWarning)),
                  () => {
                    this.displayWarningAndInitTimer();
                  }, this.configService, this.ngZone, this.changeDetectorRef, true);
              }
            }
          } else {
            this.displayWarningAndInitTimer();
          }
        } else if (this.warningLevel === 1) {
          this.appLocalStorageService.setLicenseWarningHide(false);
        }
      }
    }
  }

  ngOnDestroy() {
    if (this.intervalDisplayWarning) {
      this.intervalDisplayWarning.stop();
      this.intervalDisplayWarning = null;
    }
  }
}
