<script setup>

import { ref, onMounted, useTemplateRef, watch } from 'vue';
import { marked } from 'marked';
import { Button, PasswordInput, FormGroup, TextInput } from '@cloudron/pankow';
import PublicPageLayout from '../components/PublicPageLayout.vue';
import ProfileModel from '../models/ProfileModel.js';
import { startAuthFlow } from '../utils.js';

const profileModel = ProfileModel.create();

const footer = marked.parse(window.cloudron.footer);
const cloudronName = window.cloudron.name;

const ready = ref(false);
const busy = ref(false);
const formError = ref({});
const mode = ref('');
const form = useTemplateRef('form');
const profileLocked = ref(false);
const existingUsername = ref(false);
const username = ref('');
const displayName = ref('');
const password = ref('');
const passwordRepeat = ref('');
const dashboardUrl = ref('');
const inviteToken = ref('');

const MODE = {
  SETUP: 'setup',
  NO_USERNAME: 'noUsername',
  INVALID_TOKEN: 'invalidToken',
  DONE: 'done',
};

watch(password, () => {
  formError.value.password = null;
});

const isFormValid = ref(false);
function validateForm() {
  isFormValid.value = form.value ? form.value.checkValidity() : false;

  if (isFormValid.value) {
    if (password.value !== passwordRepeat.value) isFormValid.value = false;
  }
}

async function onSubmit() {
  if (!form.value.reportValidity() || !isFormValid.value) return;

  busy.value = true;
  formError.value = {};

  const data = {
    inviteToken: inviteToken.value,
    password: password.value,
  };

  if (!profileLocked.value) {
    if (!existingUsername.value) data.username = username.value;
    data.displayName = displayName.value;
  }

  const [error, result] = await profileModel.setupAccount(data);
  if (error) {
    if (error.status === 401) {
      mode.value = MODE.INVALID_TOKEN;
    } else if (error.status === 409) {
      formError.value.username = 'Username already taken';
    } else if (error.status === 400) {
      if (error.body && error.body.message.indexOf('Username') === 0) {
        formError.value.username = error.body.message;
      } else if (error.body && error.body.message.indexOf('Password') === 0) {
        formError.value.password = error.body.message;
        passwordRepeat.value = '';
      } else {
        formError.value.generic = error.body ? error.body.message : 'Interal error';
        console.error(error);
      }
    } else {
      formError.value.generic = error.body ? error.body.message : 'Interal error';
      console.error(error);
    }

    busy.value = false;
    return;
  }

  // set token to autologin on first oidc flow
  localStorage.cloudronFirstTimeToken = result.accessToken;

  dashboardUrl.value = await startAuthFlow('cid-webadmin', '');

  busy.value = false;
  mode.value = MODE.DONE;
}

onMounted(async () => {
  const search = decodeURIComponent(window.location.search).slice(1).split('&').map(function (item) { return item.indexOf('=') === -1 ? [item, true] : [item.slice(0, item.indexOf('=')), item.slice(item.indexOf('=')+1)]; }).reduce(function (o, k) { o[k[0]] = k[1]; return o; }, {});

  profileLocked.value = !!search.profileLocked;
  existingUsername.value = !!search.username;
  username.value = search.username || '';
  displayName.value = search.displayName || '';
  inviteToken.value = search.inviteToken;

  // Init into the correct view
  mode.value = (!existingUsername.value && profileLocked.value) ? MODE.NO_USERNAME : MODE.SETUP;

  ready.value = true;
});

</script>

<template>
  <PublicPageLayout :footer-html="footer" :cloudron-name="cloudronName">
    <div>
      <div v-if="mode === MODE.SETUP">
        <h2>{{ $t('setupAccount.welcome') }}</h2>
        <p style="margin-bottom: 8px">{{ $t('setupAccount.description') }}</p>

        <div class="error-label" v-if="formError.generic">{{ formError.generic }}</div>

        <form @submit.prevent="onSubmit()" autocomplete="off" ref="form" @input="validateForm()">
          <fieldset>
            <!-- prevents autofill -->
            <input type="password" style="display: none;"/>

            <input type="submit" style="display: none;"/>

            <FormGroup :has-error="formError.username">
              <label for="inputUsername">{{ $t('setupAccount.username') }}</label>
              <TextInput id="inputUsername" v-model="username" :disabled="profileLocked || existingUsername" required/>
              <div class="error-label" v-if="formError.username">{{ formError.username }}</div>
            </FormGroup>

            <FormGroup>
              <label for="inputDisplayName">{{ $t('setupAccount.fullName') }}</label>
              <TextInput id="inputDisplayName" v-model="displayName" :disabled="profileLocked" required/>
            </FormGroup>

            <FormGroup :has-error="formError.password">
              <label for="inputPassword">{{ $t('setupAccount.password') }}</label>
              <PasswordInput id="inputPassword" v-model="password" required/>
              <div class="error-label" v-if="formError.password">{{ formError.password }}</div>
            </FormGroup>

            <FormGroup :has-error="password !== '' && passwordRepeat !== '' && password !== passwordRepeat">
              <label for="inputPasswordRepeat">{{ $t('setupAccount.passwordRepeat') }}</label>
              <PasswordInput id="inputPasswordRepeat" v-model="passwordRepeat" required/>
              <div class="error-label" v-if="password !== '' && passwordRepeat !== '' && password !== passwordRepeat">{{ $t('setupAccount.errorPasswordNoMatch') }}</div>
            </FormGroup>
          </fieldset>
        </form>

        <br/>
        <Button :disabled="busy || !isFormValid" :loading="busy" @click="onSubmit()">{{ $t('setupAccount.setupAction') }}</Button>
      </div>

      <div v-if="mode === MODE.NO_USERNAME">
        <h2>{{ $t('setupAccount.welcome') }}</h2>
        <h3>{{ $t('setupAccount.noUsername.title') }}</h3>
        <div>{{ $t('setupAccount.noUsername.description') }}</div>
      </div>

      <div v-if="mode === MODE.INVALID_TOKEN">
        <h2>{{ $t('setupAccount.welcome') }}</h2>
        <h3 class="error-label">{{ $t('setupAccount.invalidToken.title') }}</h3>
        <div>{{ $t('setupAccount.invalidToken.description') }}</div>
      </div>

      <div v-if="mode === MODE.DONE">
        <h2>{{ $t('setupAccount.welcome') }}</h2>
        <h3>{{ $t('setupAccount.success.title') }}</h3>
        <Button :href="dashboardUrl">{{ $t('setupAccount.success.openDashboardAction') }}</Button>
      </div>
    </div>
  </PublicPageLayout>
</template>

<style>

.icon {
  margin-bottom: 20%;
}

.layout-root {
  display: flex;
  flex-grow: 1;
  overflow: hidden;
  height: 100%;
}

.layout-left {
  background-color: rgba(0,0,0,0.1);
  background-size: cover;
  background-position: center;
  flex-basis: 30%;
  justify-content: center;
  flex-direction: column;
  display: flex;
  align-items: center;
}

.layout-right {
  max-width: 400px;
  padding-left: 20px;
  flex-basis: 70%;
  display: flex;
  flex-direction: column;
  overflow: auto;
  justify-content: center;
}

</style>

