import { Component, OnDestroy, OnInit } from "@angular/core";
import { MatDialog } from "@angular/material/dialog";
import { marker } from "@biesbjerg/ngx-translate-extract-marker";
import { ImageCropperDialogComponent } from "src/app/shared/dialogs/image-cropper-dialog/image-cropper-dialog.component";
import { AccountService } from "src/app/shared/server-services/account.service";
import { AuthService } from "src/app/shared/server-services/auth.service";
import { MeRecord } from "src/app/shared/server-services/query-records/account-records";
import { WorkspaceSubscriptionAccountEventRecord } from "src/app/shared/server-services/query-records/workspace-records";
import {
  SubscriptionServiceEvent,
  SubscriptionServiceEventType,
} from "src/app/shared/server-services/subscription-event";
import { SubscriptionService } from "src/app/shared/server-services/subscription.service";
import { DialogService } from "src/app/shared/services/dialog.service";
import { RouterHandler } from "src/app/shared/services/router-handler.service";
import { TwoFactorMode } from "src/app/shared/services/server-rest-api.service";
import { TitleService } from "src/app/shared/services/title.service";
import { ClipboardService } from "src/app/shared/services/clipboard.service";
import { sideMenuActiveObserver } from "../header/header.component";
import { ChangeEmailDialogComponent } from "./change-email-dialog/change-email-dialog.component";
import { ChangePasswordDialogComponent } from "./change-password-dialog/change-password-dialog.component";
import { ChangeUsernameDialogComponent } from "./change-username-dialog/change-username-dialog.component";
import { environment } from "src/environments/environment";
import { CordovaService } from "src/app/shared/services/cordova.service";
@Component({
  selector: "app-account-settings",
  templateUrl: "./account-settings.component.html",
  styleUrls: ["./account-settings.component.scss"],
})
export class AccountSettingsComponent implements OnInit, OnDestroy {
  me: MeRecord;
  currentTwoFactorMode: TwoFactorMode;
  dataLoading: boolean = true;
  showEmail: boolean = false;
  showID: boolean = false;

  constructor(
    private dialog: MatDialog,
    private accountService: AccountService,
    private authService: AuthService,
    private dialogService: DialogService,
    private routerHandler: RouterHandler,
    private titleService: TitleService,
    private subscriptionService: SubscriptionService,
    private clipboardService: ClipboardService,
    private cordovaService: CordovaService
  ) {
    this.titleService.setTabTitle(marker("Account settings"));

    this.subscriptionService.subscribe(
      SubscriptionServiceEvent.ACCOUNT_EVENT,
      SubscriptionServiceEventType.MODIFY,
      this.onAccountChange.bind(this)
    );
  }

  onAccountChange() {
    this.accountService.getMe().then((data) => {
      this.me = Object.assign({}, data);
    });
  }

  ngOnInit(): void {
    var mePromise = this.accountService.getMe();
    var twoFAPromise = this.accountService.get2FA();

    sideMenuActiveObserver.next(false);

    Promise.all([mePromise, twoFAPromise])
      .then((res) => {
        this.me = res[0];
        this.currentTwoFactorMode = res[1].mode;
        this.dataLoading = false;
      })
      .catch((err) => console.error(err));
  }

  ngOnDestroy() {
    this.subscriptionService.unsubscribe(
      SubscriptionServiceEvent.ACCOUNT_EVENT,
      SubscriptionServiceEventType.MODIFY,
      this.onAccountChange.bind(this)
    );
  }

  openEditAvatarDialog(): void {
    var ref = this.dialog.open(ImageCropperDialogComponent);
    ref.afterClosed().subscribe((avatarImageBlob: Blob) => {
      if (!avatarImageBlob) return;

      avatarImageBlob.arrayBuffer().then((res: ArrayBuffer) => {
        this.accountService
          .setAvatar(res)
          .then((res) => {
            this.me.avatarImageKey = res;
          })
          .catch((err) => console.error("set avatar", err));
      });
    });
  }

  openEditUserNameDialog(): void {
    var ref = this.dialog.open(ChangeUsernameDialogComponent, {
      data: { userName: this.me.avatarName },
    });
    ref.afterClosed().subscribe((newUserName: string) => {
      if (!newUserName) return;

      this.accountService
        .changeAvatarName(newUserName)
        .then((res) => {
          this.dialogService.showSnackbar(
            marker("Username changed successfully!")
          );
        })
        .catch((err) => console.error(err));
    });
  }

  openEditEmailDialog(): void {
    var ref = this.dialog.open(ChangeEmailDialogComponent);
    ref.afterClosed().subscribe((newEmail: string) => {
      if (!newEmail) return;
      this.accountService
        .prepareEditEmail(newEmail)
        .then((res) => {
          this.dialogService.showSnackbar(
            marker(
              "An email has been sent to your new address with a verification link!"
            ),
            marker("OK")
          );
        })
        .catch((err) => {
          console.error(err);
          this.dialogService.openAlertDialog(
            marker("Email change"),
            marker(
              "An email has already been sent to your new address with a verification link!"
            )
          );
        });
    });
  }

  setTwoFactor(enabled: boolean): void {
    this.accountService
      .set2FA(enabled)
      .then((res) => {
        this.accountService
          .get2FA()
          .then((res2) => {
            this.currentTwoFactorMode = res2.mode;
            if (this.currentTwoFactorMode == TwoFactorMode.NONE)
              this.dialogService.showSnackbar(
                marker("Two-Factor Authentication disabled!")
              );
            else if (this.currentTwoFactorMode == TwoFactorMode.CODE)
              this.dialogService.showSnackbar(
                marker("Two-Factor Authentication enabled!")
              );
          })
          .catch((err) => {
            console.log(err);
            this.dialogService.openAlertDialog(
              marker("2FA Change"),
              marker("Wrong two-factor password!")
            );
          });
      })
      .catch((err) => this.dialogService.openAlertDialog(marker("2FA Error"), marker("Wrong two-factor password!")))
  }

  openEditPasswordDialog(): void {
    this.dialogService
      .openAlertDialog(
        marker("Warning"),
        marker(
          "You will need to re-authenticate on every web browser after a password change!"
        )
      )
      .subscribe(() => {
        var ref = this.dialog.open(ChangePasswordDialogComponent);
        ref.afterClosed().subscribe((password: string) => {
          if (!password) return;

          this.authService
            .changePassword(password)
            .then((res) => {
              this.routerHandler.navigate(["/"]);
            })
            .catch((err) => {
              console.error("Password change error", err);
            });
        });
      });
  }

  saveRecoveryKey() {
    let name = "CBNANO-SECRET-RECOVERY-KEY.TXT";
    if (this.cordovaService.isOnApp()) {
      this.cordovaService
        .getFileWriter(name)
        .then((writer) => {
          return writer
            .write(this.authService.createRecoveryKeyFile())
            .then(() => {
              writer.close();
              this.dialogService.showSnackbar(
                marker("Downloaded:") + ": " + name
              );
            });
        })
        .catch((e) => {
          console.error("Could not create the file", e);
          this.dialogService.openAlertDialog(
            marker("Download error"),
            marker("Could not create the file")
          );
        });
    } else {
      var a;
      a = document.createElement("a");
      a.href = URL.createObjectURL(this.authService.createRecoveryKeyFile());
      a.download = name;
      document.body.appendChild(a);
      a.style = "display: none";
      a.click();
      a.remove();

      this.dialogService.showSnackbar(marker("Downloaded") + ": " + name);
    }
  }

  copyContactId() {
    this.clipboardService
      .copy(this.me.id)
      .then(() => {
        this.dialogService.showSnackbar(marker("Contact ID copied!"));
      })
      .catch((err) => {
        console.error("clipboard err", err);
        this.dialogService.openAlertDialog(
          marker("Copy Error"),
          marker("Could not copy to the clipboard")
        );
      });
  }

  copyContactUrl() {
    this.clipboardService
      .copy(
        environment.site_base +
          "#contact" +
          RouterHandler.FRAGMENT_EQUAL +
          this.me.id
      )
      .then(() => {
        this.dialogService.showSnackbar(marker("Contact URL copied!"));
      })
      .catch((err) => {
        console.error("clipboard err", err);
        this.dialogService.openAlertDialog(
          marker("Copy Error"),
          marker("Could not copy to the clipboard")
        );
      });
  }
}
