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';
import { SnackBarService } from 'src/app/shared/services/snackbar.service';

@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,
    private snackbarService: SnackBarService
  ) {
    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.snackbarService.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.snackbarService.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.snackbarService.showSnackbar(marker('Sale code deleted!'));
            });
        }
      });
  }
}
