<!--
The shell layout for all user-authenticated parts of the app. It defines a top
bar with some controls and user information, and a router view for all child
pages.
-->
<script setup lang="ts">
import { AuthApiClient } from '@/api/auth'
import { getSelectedProfile } from '@/api/profile'
import { secondsUntilExpired } from '@/api/token-util'
import IdleTimeoutModal from '@/components/IdleTimeoutModal.vue'
import { LogoutReason, useAuthStore } from '@/stores/auth-store'
import { useIdleObserver } from '@idle-observer/vue3'
import { onMounted, ref, useTemplateRef, type Ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'

const route = useRoute()
const router = useRouter()
const authStore = useAuthStore()

const IDLE_TIMEOUT_SECONDS = 300
const idleTimeoutModal = useTemplateRef('idleTimeoutModal')
useIdleObserver({
  timeout: IDLE_TIMEOUT_SECONDS * 1000,
  onIdle: () => idleTimeoutModal.value?.start(),
})

const authCheckTimer: Ref<number | undefined> = ref(undefined)

onMounted(async () => {
  authStore.$subscribe(async (_, state) => {
    if (state.state === null) {
      await router.replace('/login')
    }
  })
  authCheckTimer.value = setInterval(checkAuth, 1000)
})

function onHeaderClicked() {
  try {
    router.push('/profiles/' + getSelectedProfile(route))
  } catch {
    router.push('/')
  }
}

async function checkAuth() {
  if (!authStore.state) {
    clearInterval(authCheckTimer.value)
    authCheckTimer.value = undefined
    await router.replace('/login')
    return
  }

  const secondsUntilExpiration = secondsUntilExpired(authStore.state.token)
  if (secondsUntilExpiration < 60 && secondsUntilExpiration > 5) {
    const api = new AuthApiClient()
    try {
      const newToken = await api.getNewToken()
      authStore.state.token = newToken
    } catch (err) {
      console.warn('Failed to refresh token.', err)
    }
  } else if (secondsUntilExpiration <= 0) {
    authStore.onUserLoggedOut(LogoutReason.TOKEN_EXPIRED)
  }
}
</script>

<template>
  <div>
    <header class="app-header-bar">
      <div>
        <h1
          class="app-header-text"
          @click="onHeaderClicked()"
        >
          Finnow
        </h1>
      </div>
      <div>
        <span
          class="app-user-widget"
          @click="router.push('/me')"
        >
          <font-awesome-icon icon="fa-user"></font-awesome-icon>
        </span>

        <span
          class="app-logout-button"
          @click="authStore.onUserLoggedOut(LogoutReason.USER_LOGGED_OUT)"
        >
          <font-awesome-icon icon="fa-solid fa-arrow-right-from-bracket"></font-awesome-icon>
        </span>
      </div>
    </header>

    <RouterView></RouterView>

    <IdleTimeoutModal ref="idleTimeoutModal" />
  </div>
</template>

<style lang="css">
.app-header-bar {
  background-color: var(--theme-primary);
  color: var(--text);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.app-header-text {
  display: inline;
  margin: 0 1em 0 1em;
  padding: 0;
  font-family: 'PlaywriteNL';
  font-size: 20px;
  cursor: pointer;
}

.app-header-text:hover {
  color: var(--text-muted);
}

.app-logout-button {
  cursor: pointer;
  margin-right: 0.5em;
  background-color: var(--theme-secondary);
  border-radius: 50%;
  padding: 0.35rem;
}

.app-logout-button:hover {
  color: var(--text-muted);
}

.app-user-widget {
  margin-right: 0.5em;
  cursor: pointer;
  background-color: var(--theme-secondary);
  border-radius: 50%;
  padding: 0.35rem;
}

.app-user-widget:hover {
  color: var(--text-muted);
}
</style>
