<template>
  <v-row v-if="formState.ready" dense>
    <v-col>
      <v-form ref="form">
        <button
          type="submit"
          disabled
          style="display: none"
          aria-hidden="true"
        ></button>
        <v-row dense>
          <gz-error :error-box-message="formState.errorBoxMessage"></gz-error>
          <template v-if="tfaEnabled">
            <v-col cols="12">
              <v-card data-cy="tfa" class="mx-auto my-12" max-width="600">
                <v-card-title>{{
                  $sock.t("AuthConnectAppTitle")
                }}</v-card-title>
                <v-card-text>
                  <v-btn color="accent" @click="disable()">{{
                    $sock.t("AuthDisableTwoFactor")
                  }}</v-btn>
                </v-card-text>
              </v-card>
            </v-col>
          </template>
          <template v-else>
            <v-col cols="12">
              <v-card class="mx-auto my-12" max-width="600">
                <v-card-title>{{
                  $sock.t("AuthConnectAppTitle")
                }}</v-card-title>
                <v-card-subtitle
                  >{{ $sock.t("AuthConnectAppSubTitle") }}
                </v-card-subtitle>
                <v-card-text>
                  <div class="text-center my-10">
                    <img
                      data-cy="qrCodeImage"
                      alt="Embedded QR Code"
                      :src="qCode"
                    />
                  </div>
                  {{ $sock.t("AuthConnectAppManualEntry") }}
                  <span class="text-subtitle-2 ml-2">{{ obj.s }}</span>
                  <v-text-field
                    ref="pin"
                    v-model="pin"
                    dense
                    class="mt-10"
                    :label="$sock.t('AuthEnterPin')"
                    :error-messages="form().serverErrors(this, 'pin')"
                    data-cy="tfa"
                    autofocus
                    @input="fieldValueChanged('pin')"
                    @keyup.enter="authenticate"
                  ></v-text-field>
                </v-card-text>
                <v-card-actions>
                  <v-spacer></v-spacer>
                  <v-btn color="primary" text @click="authenticate()">{{
                    $sock.t("AuthVerifyCode")
                  }}</v-btn>
                </v-card-actions>
              </v-card>
            </v-col>
          </template>
        </v-row>
      </v-form>
    </v-col>
  </v-row>
</template>
<script>
const FORM_KEY = "security";

export default {
  components: {},
  data() {
    return {
      obj: {
        s: null, // = u.TotpSecret,
        qr: null // = qrCodeImageAsBase64
      },
      pin: null,
      tfaEnabled: window.$gz.store.state.tfaEnabled,
      formState: {
        ready: false,
        dirty: false,
        valid: true,
        readOnly: false,
        loading: true,
        errorBoxMessage: null,
        appError: null,
        serverError: {}
      },
      rights: window.$gz.role.fullRightsObject()
    };
  },
  computed: {
    qCode: function() {
      return `data:image/png;base64,${this.obj.qr}`;
    }
  },
  async created() {
    const vm = this;
    try {
      await initForm(vm);
      vm.rights = window.$gz.role.fullRightsObject();
      generateMenu(vm);
      vm.formState.ready = true;
      window.$gz.form.setFormState({
        vm: vm,
        dirty: false,
        valid: true,
        loading: false,
        readOnly: false
      });
      window.$gz.eventBus.$on("menu-click", clickHandler);
      //fetch tfa secret and display here if tfa not enabled currently
      if (!this.tfaEnabled) {
        const res = await window.$gz.api.get("auth/totp");
        if (res.error) {
          throw new Error(res.error);
        } else {
          this.obj = res.data;
        }
      }
      //------------------
    } catch (err) {
      vm.formState.ready = true;
      window.$gz.errorHandler.handleFormError(err, vm);
    }
  },
  beforeDestroy() {
    window.$gz.eventBus.$off("menu-click", clickHandler);
  },
  methods: {
    form() {
      return window.$gz.form;
    },
    fieldValueChanged(ref) {
      if (!this.formState.loading && !this.formState.readOnly) {
        window.$gz.form.fieldValueChanged(this, ref);
      }
    },
    async disable() {
      const vm = this;
      vm.formState.loading = true;
      window.$gz.form.deleteAllErrorBoxErrors(vm);
      try {
        const res = await window.$gz.api.post(
          `auth/totp-disable/${vm.$store.state.userId}`
        );
        if (res.error) {
          vm.formState.serverError = res.error;
          window.$gz.form.setErrorBoxErrors(vm);
        } else {
          window.$gz.store.commit("setTfaEnabled", false);
          await window.$gz.dialog.displayLTModalNotificationMessage(
            "AuthTwoFactorDisabled"
          );
          vm.$router.push("/home-user-settings");
          window.$gz.form.setFormState({
            vm: vm,
            dirty: false
          });
        }
      } catch (error) {
        window.$gz.errorHandler.handleFormError(error, vm);
      } finally {
        vm.loading = false;
      }
    },
    async authenticate() {
      this.formState.loading = true;
      window.$gz.form.deleteAllErrorBoxErrors(this);
      try {
        const res = await window.$gz.api.post("auth/totp-validate", {
          pin: this.pin
        });
        if (res.error) {
          this.formState.serverError = res.error;
          window.$gz.form.setErrorBoxErrors(this);
        } else {
          if (res.data.ok == true) {
            window.$gz.store.commit("setTfaEnabled", true);
            //all ok, 2fa enabled
            await window.$gz.dialog.displayLTModalNotificationMessage(
              "AuthConnectCompleted"
            );
            this.$router.push("/home-user-settings");
          } else {
            window.$gz.eventBus.$emit(
              "notify-warning",
              this.$sock.t("AuthPinInvalid")
            );
          }
          window.$gz.form.setFormState({
            vm: this,
            dirty: false
          });
        }
      } catch (error) {
        window.$gz.errorHandler.handleFormError(error, this);
      } finally {
        this.loading = false;
      }
    }
  }
};

/////////////////////////////
//
//
function clickHandler(menuItem) {
  if (!menuItem) {
    return;
  }
  const m = window.$gz.menu.parseMenuItem(menuItem);
  if (m.owner == FORM_KEY && !m.disabled) {
    switch (m.key) {
      default:
        window.$gz.eventBus.$emit(
          "notify-warning",
          FORM_KEY + "::context click: [" + m.key + "]"
        );
    }
  }
}

//////////////////////
//
//
function generateMenu() {
  const menuOptions = {
    isMain: true,
    icon: "$sockiLock",
    title: "AuthTwoFactor",
    helpUrl: "home-tfa",
    formData: {
      sockType: window.$gz.type.UserOptions
    },
    menuItems: []
  };
  window.$gz.eventBus.$emit("menu-change", menuOptions);
}

/////////////////////////////////
//
//
async function initForm() {
  await fetchTranslatedText();
}

//////////////////////////////////////////////////////////
//
// Ensures UI translated text is available
//
async function fetchTranslatedText() {
  await window.$gz.translation.cacheTranslations([
    "AuthConnectAppTitle",
    "AuthConnectAppSubTitle",
    "AuthConnectAppManualEntry",
    "AuthEnterPin",
    "AuthTwoFactor",
    "AuthPinInvalid",
    "AuthConnectCompleted",
    "AuthDisableTwoFactor",
    "AuthTwoFactorDisabled",
    "AuthVerifyCode"
  ]);
}
</script>
