import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { DialogService } from 'src/app/shared/services/dialog.service';
import { ServerRestApiService } from 'src/app/shared/services/server-rest-api.service';
import { TitleService } from 'src/app/shared/services/title.service';
import { marker } from "@biesbjerg/ngx-translate-extract-marker";
import { SaleCodeRecord } from 'src/app/shared/server-services/query-records/nano-records';
import { createSaleCodeQuery, deleteSaleCodeQuery, editSaleCodeDescriptionQuery, getSaleCodesQuery } from 'src/app/shared/server-services/querys';
import { ResourceGroupCrypto } from 'src/app/shared/crypto/top/resource-group';
import { AccountService } from 'src/app/shared/server-services/account.service';
import { AuthService } from 'src/app/shared/server-services/auth.service';
import { CreateEditSaleCodeDialogComponent } from './create-edit-sale-code-dialog/create-edit-sale-code-dialog.component';
import { MatTable } from '@angular/material/table';

@Component({
  selector: 'app-sale-code-manager',
  templateUrl: './sale-code-manager.component.html',
  styleUrls: ['./sale-code-manager.component.scss']
})
export class SaleCodeManagerComponent implements OnInit {

  public saleCodes: SaleCodeRecord[];
  saleCodeColumns: string[] = ['id', 'description', 'actions'];
  @ViewChild('saleCodeTable', {static: false}) saleCodeTable: MatTable<any>;

  constructor(
    private authService: AuthService,
    private serverRestApi: ServerRestApiService,
    private titleService: TitleService,
    private dialog: MatDialog,
    private dialogService: DialogService,
    private changeDetectorRef: ChangeDetectorRef
  ) { 
    this.titleService.setTabTitle(marker("Sale Codes"));
  }

  ngOnInit(): void {
    this.serverRestApi.query({ query: getSaleCodesQuery }).then((codes: SaleCodeRecord[]) => {
      var promises: Promise<void>[] = [];

      codes.forEach(code => {
        if(code.description){
          promises.push(
            ResourceGroupCrypto.decrypt(code.description, this.authService.getSelfAccountKeyring())
              .then((res: string) => {code.descriptionDecoded = {valid: true, text: res}})
              .catch(err => {code.descriptionDecoded = {valid: false, text: '[Decryption Error]'}})
            );
        }
        else{
          code.descriptionDecoded = {valid: true, text:''}
        }
      });

      Promise.all(promises)
        .then(res => {
          console.log(codes);
          this.saleCodes = codes;
        })
        .catch(err => console.error("Sale code all error", err));
    });
  }

  public createSaleCode(): void{
    var dialogRef = this.dialog.open(CreateEditSaleCodeDialogComponent);
    dialogRef.afterClosed().subscribe((newSaleCode: SaleCodeRecord) => {
      if(!newSaleCode) return;

      ResourceGroupCrypto.encrypt(newSaleCode.descriptionDecoded.text, this.authService.getSelfAccountKeyring()).then(encryptedDescription => {
        this.serverRestApi.mutate({query: createSaleCodeQuery, variables: {description: encryptedDescription}}).then((codeId: string) => {
          newSaleCode.id = codeId;
          this.saleCodes.push(newSaleCode);
  
          this.changeDetectorRef.detectChanges();
          this.saleCodeTable.renderRows();

          this.dialogService.showSnackbar(marker("Sale code created!"));
        });
      }).catch(err => console.error("encrypt error", err));
    });
  }

  public editSaleCode(saleCode: SaleCodeRecord): void{
    var dialogRef = this.dialog.open(CreateEditSaleCodeDialogComponent, {data: saleCode});
    dialogRef.afterClosed().subscribe((updatedSaleCode: SaleCodeRecord) => {
      if(!updatedSaleCode) return;

      ResourceGroupCrypto.encrypt(updatedSaleCode.descriptionDecoded.text, this.authService.getSelfAccountKeyring()).then(encryptedDescription => {
        this.serverRestApi.mutate({query: editSaleCodeDescriptionQuery, variables: {saleCode: updatedSaleCode.id, description: encryptedDescription}}).then((res) => {
  
          this.changeDetectorRef.detectChanges();
          this.saleCodeTable.renderRows();

          this.dialogService.showSnackbar(marker("Sale code modified!"));
        });
      }).catch(err => console.error("encrypt error", err));
    });
  }

  public deleteSaleCode(saleCode: SaleCodeRecord): void{
    this.dialogService.openConfirmDialog(marker("Delete Sale Code"), marker("Are you sure you want to delete this sale code?"))
      .subscribe((confirm: boolean) => {
        if(confirm){
          this.serverRestApi.mutate({query: deleteSaleCodeQuery, variables: {saleCode: saleCode.id}})
            .then(res => {
              this.saleCodes = this.saleCodes.filter(sc => sc.id != saleCode.id);

              this.changeDetectorRef.detectChanges();
              this.saleCodeTable?.renderRows();

              this.dialogService.showSnackbar(marker("Sale code deleted!"));
            });
        }
      });
  }

}
