<script setup>

import { ref, onMounted } from 'vue';
import { Button, PasswordInput, TextInput, fetcher, FormGroup } from '@cloudron/pankow';
import PublicPageLayout from '../components/PublicPageLayout.vue';

const ready = ref(false);
const busy = ref(false);
const passwordError = ref(null);
const totpError = ref(null);
const internalError = ref(null);
const oidcError = ref('');
const username = ref('');
const password = ref('');
const totpToken = ref('');
const totpTokenRequired = ref(false);

// coming from oidc_login.html template
const name = window.cloudron.name;
const note = window.cloudron.note;
const iconUrl = window.cloudron.iconUrl;
const footer = window.cloudron.footer;
const submitUrl = window.cloudron.submitUrl;

async function onSubmit() {
  busy.value = true;
  passwordError.value = false;
  totpError.value = false;
  internalError.value = false;
  oidcError.value = '';

  const body = {
    username: username.value,
    password: password.value,
    totpToken: totpToken.value
  };

  try {
    const res = await fetcher.post(submitUrl, body);
    if (res.status === 410) {
      // the oidc login session is old
      window.location.reload();
    } else if (res.status === 401) {
      if (res.body.message.indexOf('totpToken') !== -1) {
        totpError.value = totpTokenRequired.value; // only set on second try coming from login
        totpTokenRequired.value = true;
        totpToken.value = '';
        setTimeout(() => document.getElementById('inputTotpToken').focus(), 0);
      } else {
        password.value = '';
        passwordError.value = true;
        document.getElementById('inputPassword').focus();
      }
    } else if (res.status === 200 ) {
      if (res.body.redirectTo) return window.location.href = res.body.redirectTo;
      console.error('login success but missing redirectTo in data:', res.body);
      internalError.value = true;
    } else if (res.status >= 400 && res.status < 500) {
      oidcError.value = 'OpenID Error: ' + (res.body.message || '') + '. Will reload in 5 seconds';
      setTimeout(() => window.location.href = '/', 5000);
    } else {
      internalError.value = true;
    }
  } catch (error) {
    internalError.value = true;
    console.error(error);
  }

  busy.value = false;
}

onMounted(async () => {
  // placed optionally in local storage by setupaccount.js
  const autoLoginToken = localStorage.cloudronFirstTimeToken;
  if (autoLoginToken) {
    localStorage.removeItem('cloudronFirstTimeToken');
    try {
      const res = await fetcher.post(submitUrl, { autoLoginToken });
      window.location.href = res.body.redirectTo || '/';
      return;
    } catch (error) {
      console.error('Failed to use autologin token', error);
    }
  }

  ready.value = true;
});

</script>

<template>
  <PublicPageLayout v-if="ready" :footerHtml="footer" :icon-url="iconUrl" :cloudron-name="name">
    <div>
      <h2>{{ $t('login.loginTo') }}</h2>
      <p v-html="note" style="margin-bottom: 8px"></p>

      <form @submit.prevent="onSubmit" v-if="!totpTokenRequired">
        <fieldset :disabled="busy">
          <input type="submit" style="display: none;"/>

          <FormGroup>
            <label for="inputUsername">{{ $t('login.username') }}</label>
            <TextInput id="inputUsername" v-model="username" autofocus required/>
          </FormGroup>

          <FormGroup>
            <label for="inputPassword">{{ $t('login.password') }}</label>
            <PasswordInput id="inputPassword" v-model="password" required/>
          </FormGroup>

          <div class="error-label" v-if="passwordError">{{ $t('login.errorIncorrectCredentials') }}</div>
          <div class="error-label" v-if="internalError">{{ $t('login.errorInternal') }}</div>
          <div class="error-label" v-if="oidcError">{{ oidcError }}</div>
        </fieldset>

        <div class="actions">
          <Button id="loginSubmitButton" @click="onSubmit" :disabled="busy || (!username || !password)" :loading="busy">{{ $t('login.signInAction') }}</Button>
          <a href="/passwordreset.html">{{ $t('login.resetPasswordAction') }}</a>
        </div>
      </form>

      <form @submit.prevent="onSubmit" v-if="totpTokenRequired" autocomplete="off">
        <fieldset :disabled="busy">
          <input type="submit" style="display: none;"/>

          <FormGroup :has-error="totpError">
            <label for="inputTotpToken">{{ $t('login.2faToken') }}</label>
            <TextInput id="inputTotpToken" v-model="totpToken" required/>
          </FormGroup>

          <div class="error-label" v-if="totpError">{{ $t('login.errorIncorrect2FAToken') }}</div>
        </fieldset>

        <div class="actions">
          <Button id="totpTokenSubmitButton" @click="onSubmit" :disabled="busy || !totpToken" :loading="busy">{{ $t('login.signInAction') }}</Button>
        </div>
      </form>
    </div>
  </PublicPageLayout>
</template>

<style scoped>

.actions {
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.actions a {
  margin-top: 12px;
  font-size: 0.9em;
}

@media (max-width: 576px) {
  .actions {
    align-items: unset;
  }
}

</style>
