<script setup>

import { ref, useTemplateRef } from 'vue';
import { Button, ClipboardAction, Dialog, TextInput, InputGroup, FormGroup } from '@cloudron/pankow';
import { startRegistration } from '@simplewebauthn/browser';
import ProfileModel from '../models/ProfileModel.js';

const props = defineProps({
  mandatory2FA: { type: Boolean, default: false },
  has2FA: { type: Boolean, default: false }
});

const emit = defineEmits([ 'success' ]);

const profileModel = ProfileModel.create();

const dialog = useTemplateRef('dialog');
const setupMode = ref('');
const totpSecret = ref('');
const totpToken = ref('');
const totpQRCode = ref('');
const totpEnableError = ref('');
const passkeyRegisterError = ref('');
const passkeyRegisterBusy = ref(false);

async function onTotpEnable() {
  const [error] = await profileModel.enableTotp(totpToken.value);
  if (error) {
    totpToken.value = '';
    return totpEnableError.value = error.body ? error.body.message : 'Internal error';
  }

  emit('success');
  dialog.value.close();
}

async function onRegisterPasskey() {
  passkeyRegisterBusy.value = true;
  passkeyRegisterError.value = '';

  try {
    const [optionsError, options] = await profileModel.getPasskeyRegistrationOptions();
    if (optionsError) {
      passkeyRegisterError.value = optionsError.body?.message || 'Failed to get registration options';
      passkeyRegisterBusy.value = false;
      return;
    }

    const credential = await startRegistration({ optionsJSON: options });

    const [registerError] = await profileModel.registerPasskey(credential, 'Cloudron');
    if (registerError) {
      passkeyRegisterError.value = registerError.body?.message || 'Failed to register passkey';
      passkeyRegisterBusy.value = false;
      return;
    }

    emit('success');
    dialog.value.close();
  } catch (error) {
    passkeyRegisterError.value = error.message || 'Passkey registration failed';
  }

  passkeyRegisterBusy.value = false;
}

async function loadTotpSecret() {
  const [error, result] = await profileModel.setTotpSecret();
  if (error) return console.error(error);

  totpSecret.value = result.secret;
  totpQRCode.value = result.qrcode;
}

defineExpose({
  async open(method) {
    setupMode.value = method || 'passkey';
    totpEnableError.value = '';
    totpToken.value = '';
    passkeyRegisterError.value = '';

    dialog.value.open();

    if (setupMode.value === 'totp') await loadTotpSecret();
  },
  close() {
    dialog.value.close();
  }
});

async function switchMode(mode) {
  setupMode.value = mode;
  if (mode === 'totp' && !totpSecret.value) await loadTotpSecret();
}

</script>

<template>
  <Dialog ref="dialog" :title="setupMode === 'totp' ? $t('profile.enableTotp.title') : $t('profile.enablePasskey.title')" :dismissable="!props.mandatory2FA || props.has2FA">
    <div>
      <p class="text-warning" v-if="props.mandatory2FA && !props.has2FA">{{ $t('profile.enable2FA.mandatorySetup') }}</p>

      <!-- Passkey Setup -->
      <div v-if="setupMode === 'passkey'">
        <p v-html="$t('profile.enable2FA.passkeyDescription', { googleAuthenticatorPlayStoreLink: 'https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2', googleAuthenticatorITunesLink: 'https://itunes.apple.com/us/app/google-authenticator/id388497605', freeOTPPlayStoreLink: 'https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp', freeOTPITunesLink: 'https://itunes.apple.com/us/app/freeotp-authenticator/id872559395'})"></p>
        <div style="text-align: center;">
          <Button @click="onRegisterPasskey()" :loading="passkeyRegisterBusy" :disabled="passkeyRegisterBusy">{{ $t('profile.enable2FA.registerPasskey') }}</Button>
          <div class="error-label" v-if="passkeyRegisterError">{{ passkeyRegisterError }}</div>
        </div>
        <p v-if="props.mandatory2FA && !props.has2FA" style="text-align: center; margin-top: 15px;">
          <a href="#" @click.prevent="switchMode('totp')">{{ $t('profile.enable2FA.switchToTotp') }}</a>
        </p>
      </div>

      <!-- TOTP Setup -->
      <div v-if="setupMode === 'totp'">
        <p v-html="$t('profile.enable2FA.authenticatorAppDescription', { googleAuthenticatorPlayStoreLink: 'https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2', googleAuthenticatorITunesLink: 'https://itunes.apple.com/us/app/google-authenticator/id388497605', freeOTPPlayStoreLink: 'https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp', freeOTPITunesLink: 'https://itunes.apple.com/us/app/freeotp-authenticator/id872559395'})"></p>
        <div style="text-align: center;">
          <img :src="totpQRCode" style="border-radius: 10px; margin-bottom: 10px"/>
          <small>{{ totpSecret }} <ClipboardAction plain :value="totpSecret"/></small>
        </div>
        <br/>
        <form @submit.prevent="onTotpEnable()">
          <input type="submit" style="display: none;" :disabled="!totpToken"/>
          <FormGroup style="text-align: left;">
            <label for="totpTokenInput">{{ $t('profile.enable2FA.token') }}</label>
            <InputGroup>
              <TextInput v-model="totpToken" id="totpTokenInput" style="flex-grow: 1;"/>
              <Button @click="onTotpEnable()" :disabled="!totpToken">{{ $t('profile.enable2FA.enable') }}</Button>
            </InputGroup>
            <div class="error-label" v-if="totpEnableError">{{ totpEnableError }}</div>
          </FormGroup>
        </form>
        <p v-if="props.mandatory2FA && !props.has2FA" style="text-align: center; margin-top: 15px;">
          <a href="#" @click.prevent="switchMode('passkey')">{{ $t('profile.enable2FA.switchToPasskey') }}</a>
        </p>
      </div>
    </div>
  </Dialog>
</template>
