// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
<template>
  <div class="center">
    <a-form
      :ref="formRef"
      :model="form"
      :rules="rules">
      <img
        v-if="$config.banner"
        :style="{
          width: $config.theme['@banner-width'],
          height: $config.theme['@banner-height'],
        }"
        :src="$config.banner"
        class="center-align"
        alt="logo">
      <br />
      <h1 style="text-align: center; font-size: 24px; color: gray"> {{ $t('label.two.factor.authentication') }} </h1>
    <p style="font-size: 16px;" v-html="$t('message.two.fa.login.page')"></p>
    <h3> {{ $t('label.select.2fa.provider') }} </h3>
      <a-row :gutter="24">
        <a-col :md="24" :lg="22">
          <a-form-item v-ctrl-enter="submitPin" ref="selectedProvider" name="selectedProvider">
             <a-select
              v-model:value="form.selectedProvider"
              @change="val => { handleSelectChange(val) }">
              <a-select-option
                v-for="(opt) in providers"
                :key="opt"
                :value="opt">
                <div>
                  <span v-if="opt === 'totp'">
                    <google-outlined />
                    Google Authenticator
                  </span>
                  <span v-if="opt === 'othertotp'">
                    <field-time-outlined />
                    Other TOTP Authenticators
                  </span>
                  <span v-if="opt === 'staticpin'">
                    <lock-outlined />
                    Static PIN
                  </span>
                </div>
              </a-select-option>
            </a-select>
          </a-form-item>
        </a-col>

        <a-col :md="24" :lg="2">
          <a-form-item>
            <div v-if="selectedProvider">
              <a-button ref="submit" type="primary" :disabled="twoFAenabled" @click="setup2FAProvider">{{ $t('label.setup') }}</a-button>
              <tooltip-button
                tooltipPlacement="top"
                :tooltip="$t('label.accept.project.invitation')"
                icon="check-outlined"
                size="small"
                @onClick="setup2FAProvider()"/>
              <tooltip-button
                tooltipPlacement="top"
                :tooltip="$t('label.decline.invitation')"
                type="primary"
                :danger="true"
                icon="close-outlined"
                size="small"
                @onClick="setup2FAProvider()"/>
            </div>
          </a-form-item>
        </a-col>
      </a-row>

      <div v-if="twoFAenabled">
        <div v-if="form.selectedProvider !== 'staticpin'">
          <br />
          <p v-html="$t('message.two.fa.register.account.login.page')"></p>
          <vue-qrious
            class="center-align"
            :value="totpUrl"
            size="150"
            @change="onDataUrlChange"
          />
          <div style="text-align: center"> <a @click="showConfiguredPin"> {{ $t('message.two.fa.view.setup.key') }}</a></div>
        </div>
        <div v-if="form.selectedProvider === 'staticpin'">
          <br>
          <p v-html="$t('message.two.fa.staticpin.login.page')"></p>
          <br>
          <div> <a @click="showConfiguredPin"> {{ $t('message.two.fa.view.static.pin') }}</a></div>
        </div>
        <div v-if="form.selectedProvider">
          <br />
          <h3> {{ $t('label.enter.code') }} </h3>
          <a-row :gutter="24">
            <a-col :md="24" :lg="22">
              <a-form-item @finish="submitPin" v-ctrl-enter="submitPin" name="code" ref="code">
                <a-input-password
                  v-model:value="form.code"
                  placeholder="xxxxxx" />
              </a-form-item>
            </a-col>
            <a-col :md="24" :lg="2">
              <a-form-item>
                  <a-button ref="submit" type="primary" :disabled="verifybuttonstate" @click="submitPin">{{ $t('label.verify') }}</a-button>
              </a-form-item>
            </a-col>
          </a-row>
        </div>

        <a-modal
          v-if="showPin"
          :visible="showPin"
          :title="$t(form.selectedProvider === 'staticpin'? 'label.two.factor.authentication.static.pin' : 'label.two.factor.authentication.secret.key')"
          :closable="true"
          :footer="null"
          @cancel="onCloseModal"
          centered
          width="450px">
          <div> {{ pin }} </div>
        </a-modal>
      </div>
    </a-form>
  </div>
</template>
<script>

import { api } from '@/api'
import { ref, reactive, toRaw } from 'vue'
import store from '@/store'
import VueQrious from 'vue-qrious'
import eventBus from '@/config/eventBus'
export default {
  name: 'SetupTwoFaAtLogin',
  props: {
    resource: {
      type: Object,
      required: true
    }
  },
  components: {
    VueQrious
  },
  data () {
    return {
      totpUrl: '',
      dataUrl: '',
      pin: '',
      showPin: false,
      twoFAenabled: false,
      twoFAverified: false,
      providers: [],
      selectedProvider: null,
      verifybuttonstate: false
    }
  },
  mounted () {
    this.list2FAProviders()
  },
  created () {
    this.initForm()
    eventBus.on('action-closing', (args) => {
      if (args.action.api === 'setupUserTwoFactorAuthentication' && this.twoFAenabled && !this.twoFAverified) {
        this.disable2FAProvider()
      }
    })
  },
  methods: {
    initForm () {
      this.formRef = ref()
      this.form = reactive({})
      this.rules = reactive({
        code: [{ required: true, message: this.$t('message.error.authentication.code') }]
      })
    },
    onDataUrlChange (dataUrl) {
      this.dataUrl = dataUrl
    },
    handleSelectChange (val) {
      if (this.twoFAenabled) {
        api('setupUserTwoFactorAuthentication', { enable: 'false' }).then(response => {
          this.pin = ''
          this.username = ''
          this.totpUrl = ''
          this.dataUrl = ''
          this.showPin = false
          this.twoFAenabled = false
          this.twoFAverified = false
        }).catch(error => {
          this.$notification.error({
            message: this.$t('message.request.failed'),
            description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
          })
        })
      }
      this.selectedProvider = val
      this.twoFAenabled = false
    },
    setup2FAProvider () {
      this.formRef.value.validate().then(() => {
        const values = toRaw(this.form)
        this.selectedProvider = values.selectedProvider
        var provider
        if (this.selectedProvider === 'othertotp') {
          provider = 'totp'
        } else {
          provider = this.selectedProvider
        }
        api('setupUserTwoFactorAuthentication', { provider: provider }).then(response => {
          this.pin = response.setupusertwofactorauthenticationresponse.setup2fa.secretcode
          if (this.selectedProvider === 'totp' || this.selectedProvider === 'othertotp') {
            this.username = response.setupusertwofactorauthenticationresponse.setup2fa.username

            var issuer = 'CloudStack'
            if (store.getters.twoFaIssuer !== '' && store.getters.twoFaIssuer !== undefined) {
              issuer = store.getters.twoFaIssuer
            }
            this.totpUrl = 'otpauth://totp/' + issuer + ':' + this.username + '?secret=' + this.pin + '&issuer=' + issuer

            this.showPin = false
          }
          if (this.selectedProvider === 'staticpin') {
            this.showPin = true
          }
          this.twoFAenabled = true
          this.twoFAverified = false
        }).catch(error => {
          this.$notification.error({
            message: this.$t('message.request.failed'),
            description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
          })
        })
      })
    },
    disable2FAProvider () {
      api('setupUserTwoFactorAuthentication', { enable: false }).then(response => {
        this.showPin = false
        this.twoFAenabled = false
        this.twoFAverified = false
      }).catch(error => {
        this.$notification.error({
          message: this.$t('message.request.failed'),
          description: (error.response && error.response.headers && error.response.headers['x-description']) || error.message
        })
      })
    },
    list2FAProviders () {
      api('listUserTwoFactorAuthenticatorProviders', {}).then(response => {
        var providerlist = response.listusertwofactorauthenticatorprovidersresponse.providers || []
        var providernames = []
        for (const provider of providerlist) {
          providernames.push(provider.name)
          if (provider.name === 'totp') {
            providernames.push('othertotp')
          }
        }
        this.providers = providernames
      })
    },
    submitPin () {
      this.formRef.value.validate().then(() => {
        const values = toRaw(this.form)
        if (values.code !== null) {
          this.verifybuttonstate = true
        }
        api('validateUserTwoFactorAuthenticationCode', { codefor2fa: values.code }).then(response => {
          this.$message.success({
            content: `${this.$t('label.action.enable.two.factor.authentication')}`,
            duration: 2
          })
          this.$notification.destroy()
          this.$store.commit('SET_COUNT_NOTIFY', 0)
          this.$store.commit('SET_LOGIN_FLAG', true)
          this.$router.push({ path: '/dashboard' }).catch(() => {})

          this.twoFAverified = true
          this.$emit('refresh-data')
        }).catch(() => {
          this.$notification.error({
            message: this.$t('message.request.failed'),
            description: this.$t('message.error.setup.2fa')
          })
          this.$store.dispatch('Logout').then(() => {
            this.$router.replace({ path: '/user/login' })
          })
        })
      })
    },
    closeAction () {
      this.$emit('close-action')
    },
    showConfiguredPin () {
      this.showPin = true
    },
    onCloseModal () {
      this.showPin = false
    }
  }
}
</script>

<style scoped>
  .center {
    background-color: transparent;
    padding: 80px 500px 70px 500px;
  }
  .center-align {
    display: block;
    margin-left: auto;
    margin-right: auto;
  }
  .form-align {
    display: flex;
    flex-direction: row;
  }
  .top-padding {
    padding-top: 35px;
  }
  .container {
    display: flex;
  }

</style>
