<script setup lang="ts">
import { AuthApiClient } from '@/api/auth'
import { ApiError } from '@/api/base'
import { getLastProfileUsed, ProfileApiClient } from '@/api/profile'
import AppButton from '@/components/common/AppButton.vue'
import AppForm from '@/components/common/form/AppForm.vue'
import FormControl from '@/components/common/form/FormControl.vue'
import FormGroup from '@/components/common/form/FormGroup.vue'
import { LogoutReason, useAuthStore } from '@/stores/auth-store'
import { showAlert } from '@/util/alert'
import { hideLoader, showLoader } from '@/util/loader'
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'

const router = useRouter()
const route = useRoute()
const authStore = useAuthStore()
const apiClient = new AuthApiClient()
const isDev = import.meta.env.DEV

const username = ref('')
const password = ref('')
const disableForm = ref(false)

async function doLogin() {
  disableForm.value = true
  showLoader()
  try {
    const token = await apiClient.login(username.value, password.value)
    authStore.onUserLoggedIn(username.value, token)
    const profiles = await new ProfileApiClient().getProfiles()
    const lastProfileUsed = getLastProfileUsed()
    hideLoader()
    if ('next' in route.query && typeof route.query.next === 'string') {
      await router.replace(route.query.next)
    } else if (profiles.length === 1) {
      // If there's only one available profile, go right to it.
      await router.replace(`/profiles/${profiles[0].name}`)
    } else if (lastProfileUsed !== null && profiles.map((p) => p.name).includes(lastProfileUsed)) {
      // If we know what profile the user was last using, go to that.
      await router.replace(`/profiles/${lastProfileUsed}`)
    } else {
      // Otherwise, go to the profiles page so the user can choose.
      await router.replace('/profiles')
    }
  } catch (err) {
    hideLoader()
    if (err instanceof ApiError) {
      await showAlert(err.message)
    } else {
      await showAlert('Request failed: ' + JSON.stringify(err))
    }
  } finally {
    disableForm.value = false
  }
}

async function doRegister() {
  disableForm.value = true
  showLoader()
  try {
    await apiClient.register(username.value, password.value)
    await doLogin()
  } catch (err) {
    hideLoader()
    if (err instanceof ApiError) {
      await showAlert(err.message)
    } else {
      await showAlert('Request failed: ' + JSON.stringify(err))
    }
  } finally {
    disableForm.value = false
  }
}

function isDataValid() {
  return username.value.length > 0 && password.value.length >= 8
}

function generateSampleData() {
  fetch(import.meta.env.VITE_API_BASE_URL + '/sample-data', {
    method: 'POST',
  })
}
</script>
<template>
  <div class="app-login-panel">
    <h1 style="text-align: center; margin-bottom: 0.5rem; font-family: 'PlaywriteNL'">Finnow</h1>
    <p style="text-align: center; font-weight: 600; margin-top: 0">
      <em>Personal finance for the modern era.</em>
    </p>

    <p
      v-if="authStore.logoutReason === LogoutReason.INACTIVITY_TIMEOUT"
      class="alert-banner alert-banner-warning"
    >
      You were logged out automatically after being inactive for a while. Please log in again to
      resume your session.
    </p>

    <p
      v-if="authStore.logoutReason === LogoutReason.TOKEN_EXPIRED"
      class="alert-banner alert-banner-warning"
    >
      You were logged out because your session expired. Please log in again to resume your session.
    </p>

    <AppForm @submit="doLogin()">
      <FormGroup>
        <FormControl
          label="Username"
          class="login-control"
        >
          <input
            class="login-input"
            type="text"
            v-model="username"
            :disabled="disableForm"
          />
        </FormControl>
        <FormControl
          label="Password"
          class="login-control"
        >
          <input
            class="login-input"
            id="password-input"
            type="password"
            v-model="password"
            :disabled="disableForm"
          />
        </FormControl>
      </FormGroup>
      <div style="display: flex; margin-left: 1rem; margin-right: 1rem">
        <AppButton
          type="submit"
          :disabled="disableForm || !isDataValid()"
          style="flex-grow: 1"
          >Login
        </AppButton>
        <AppButton
          type="button"
          theme="secondary"
          :disabled="disableForm || !isDataValid()"
          @click="doRegister()"
        >
          Register</AppButton
        >
      </div>
      <div v-if="isDev">
        <AppButton
          type="button"
          @click="generateSampleData()"
          >Generate Sample Data</AppButton
        >
      </div>

      <!-- Disclaimer note that this project is still a work-in-progress! -->
      <div class="font-size-small mx-1">
        <p>
          <strong>Note:</strong> Finnow is still under development, and may be prone to bugs or
          unexpected data loss. Proceed to register and use this service at your own risk.
        </p>
        <p>
          Data is stored securely in protected cloud storage, but may be accessed by a system
          administrator in case of errors or debugging. Please <strong>DO NOT</strong> store any
          sensitive financial credentials that you aren't okay with losing or potentially being
          leaked. Finnow is not responsible for any lost or compromised data.
        </p>
      </div>
    </AppForm>
  </div>
</template>
<style lang="css">
.app-login-panel {
  max-width: 40ch;
  margin: 0 auto;
}

.login-input {
  max-width: 200px;
  margin-top: 0.25rem;
}

.login-control {
  flex-grow: 0;
  margin: 0.5rem auto;
}
</style>
