import { ChangeDetectorRef, Component, OnInit, ViewChild, ViewChildren } from "@angular/core";
import { marker } from "@biesbjerg/ngx-translate-extract-marker";
import { getNanoBundleLicensesQuery, getNanoLicensesQuery, getRecurringOrdersQuery, redeemLicenseTokenQuery } from "src/app/shared/server-services/querys";
import { ServerRestApiService } from "src/app/shared/services/server-rest-api.service";
import { TitleService } from "src/app/shared/services/title.service";
import { sideMenuActiveObserver } from "../header/header.component";
import { LicenseBundleRecord, LicenseRecord, RecurringOrderRecord } from "src/app/shared/server-services/query-records/nano-records";
import { MatDialog } from "@angular/material/dialog";
import { BundledLicensesDialogComponent } from "./bundled-licenses-dialog/bundled-licenses-dialog.component";
import { RedeemTokenDialogComponent } from "./redeem-token-dialog/redeem-token-dialog.component";
import { RecurringOrderDetailDialogComponent } from "./recurring-order-detail-dialog/recurring-order-detail-dialog.component";
import { DialogService } from "src/app/shared/services/dialog.service";
import { MatTable } from "@angular/material/table";
import { CordovaService } from "src/app/shared/services/cordova.service";

import { environment } from "src/environments/environment";

@Component({
  selector: "app-nano-license",
  templateUrl: "./nano-license.component.html",
  styleUrls: ["./nano-license.component.scss"],
})
export class NanoLicenseComponent implements OnInit{
  licenseColumns: string[] = ['id', 'number', 'expiration', 'recurrence', 'revoked'];
  bundleColumns: string[] = ['id', 'number', 'expiration', 'months', 'revoked', 'action'];
  licenses: LicenseRecord[];
  bundles: LicenseBundleRecord[];
  recurringOrders: RecurringOrderRecord[];
  loading: boolean = false;
  isOnApp: boolean = false;

  @ViewChild('licenseTable', {static: false}) licenseTable: MatTable<any>;

  constructor(
    private serverRestApi: ServerRestApiService,
    private titleService: TitleService,
    private dialog: MatDialog,
    private dialogService: DialogService,
    private changeDetectorRef: ChangeDetectorRef,
    private cordovaService: CordovaService
  ) {
    this.titleService.setTabTitle(marker("Licenses"));
    this.isOnApp = this.cordovaService.isOnApp();
  }

  ngOnInit()
  {
    sideMenuActiveObserver.next(false);
    this.getLicense();
  }

  public getLicense() {
    this.serverRestApi.query({ query: getNanoLicensesQuery }).then((res) => {
      this.licenses = res.licenses;
      this.bundles = res.bundles;

      this.serverRestApi.query({query: getRecurringOrdersQuery}).then((res) => {
  
        this.recurringOrders = res.response;
  
        for(let recurringOrder of this.recurringOrders){
          var license = this.licenses.find(l => l.id == recurringOrder.license_id);
          if(license){
            license.recurringOrder = recurringOrder;
          }
        }
      });

      this.sortLicensesAndBundles();

      this.changeDetectorRef.detectChanges();
      if (this.licenses.length > 0) this.licenseTable.renderRows();
    });
  }

  public isExpired(license){
    return new Date(license.expiration * 1000) < new Date();
  }

  public showBundleLicenses(bundle: LicenseBundleRecord){
    if(this.loading) return;

    this.loading = true;

    this.getTokens(bundle.id).then((res) => {
      var dialogRef = this.dialog.open(BundledLicensesDialogComponent, {data: res});
      this.loading = false;
    });
  }

  public downloadBundleLicenses(bundle: LicenseBundleRecord){
    if(this.loading) return;

    this.loading = true;

    this.getTokens(bundle.id).then((res) => {
      var tokensString = (<string[]>res.tokens).join(',\r\n');
      const blob = new Blob([tokensString], { type: 'text/csv' });
      const url= window.URL.createObjectURL(blob);
      var a;
      a = document.createElement("a");
      a.href = url;
      a.download = `CBNANO-BUNDLED-LICENSES-${bundle.id}.csv`;
      a.click();
    })
    .finally(() => this.loading = false);
  }

  public showRedeemDialog(): void{
    var dialogRef = this.dialog.open(RedeemTokenDialogComponent);
    dialogRef.afterClosed().subscribe((tokenString: string) => {
     if(!tokenString) return;

      this.serverRestApi.mutate({query: redeemLicenseTokenQuery, variables: {licenseToken: tokenString.trim()}})
      .then(() => {
        this.dialogService.showSnackbar(marker("Token successfully redeemed!"));
        this.getLicense();
      })
      .catch((err) => {
        console.error(err); 
        this.dialogService.openAlertDialog(marker("Invalid token"), marker("Could not redeem token. Please make sure you are using a valid, unused token."));
      });
    });
  }

  public openRecurringOrderDetail(recurringOrder: RecurringOrderRecord): void{
    var dialogRef = this.dialog.open(RecurringOrderDetailDialogComponent, {data: recurringOrder});
    dialogRef.afterClosed().subscribe((canceled: boolean) => {
      if(canceled)
        this.getLicense();
    });
  }

  private getTokens(bundleId: string): Promise<any>{
    return this.serverRestApi.query({query: getNanoBundleLicensesQuery, variables: {id: bundleId}});
  }

  private sortLicensesAndBundles(){
    this.licenses.sort(this.sortFn);
    this.bundles.sort(this.sortFn);
  }
  private sortFn = (a, b) =>{
    if(a.revoked || b.revoked || this.isExpired(a) || this.isExpired(b)){
      if(a.revoked)
        return 1;
      if(b.revoked)
        return -1;
      if(this.isExpired(a))
        return 1;
      if(this.isExpired(b))
        return -1;
    }
    else{
      return a.expiration - b.expiration;
    }
  }
}
