<script setup lang="ts">

import { onMounted, onUnmounted, computed, ref, watch } from 'vue'

import { useRoute, useRouter } from 'vue-router'

import { darkTheme, NConfigProvider, NMessageProvider, NDialogProvider, NNotificationProvider } from 'naive-ui'

import { useI18n } from 'vue-i18n'

import { getThemeOverrides } from '@/styles/theme'

import { useTheme } from '@/composables/useTheme'

import AppSidebar from '@/components/layout/AppSidebar.vue'

import AppTopBar from '@/components/layout/AppTopBar.vue'

import AppLogo from '@/components/common/AppLogo.vue'

import { useKeyboard } from '@/composables/useKeyboard'

import { useAppStore } from '@/stores/hermes/app'

import SessionSearchModal from '@/components/hermes/chat/SessionSearchModal.vue'

import AuthEventListener from '@/components/auth/AuthEventListener.vue'

import DefaultCredentialPrompt from '@/components/auth/DefaultCredentialPrompt.vue'



const { isDark, isComic } = useTheme()

const { t } = useI18n()

const appStore = useAppStore()

const route = useRoute()

const router = useRouter()

const ready = ref(false)



const themeOverrides = computed(() => getThemeOverrides(isDark.value, isComic.value))

const naiveTheme = computed(() => isDark.value ? darkTheme : null)



const isLoginPage = computed(() => route.name === 'login')



const nodeVersionLow = computed(() => {

  const v = appStore.nodeVersion

  const major = parseInt(v.split('.')[0], 10)

  return !isNaN(major) && major < 23

})



watch(() => route.path, () => {

  appStore.closeSidebar()

})



router.isReady().then(() => {

  ready.value = true

})



onMounted(() => {

  if (!isLoginPage.value) {

    appStore.loadModels()

    appStore.startHealthPolling()

  }

})



onUnmounted(() => {

  appStore.stopHealthPolling()

})



useKeyboard()

</script>



<template>

  <NConfigProvider :theme="naiveTheme" :theme-overrides="themeOverrides">

    <NMessageProvider>

      <AuthEventListener />

      <NDialogProvider>

        <NNotificationProvider>

          <div v-if="nodeVersionLow && ready" class="node-warning-bar">

            {{ t('sidebar.nodeVersionWarning', { version: appStore.nodeVersion }) }}

          </div>

          <div v-if="ready" class="app-shell" :class="{ 'no-chrome': isLoginPage, 'has-warning': nodeVersionLow }">

            <AppTopBar v-if="!isLoginPage" />

            <button v-if="!isLoginPage" class="hamburger-btn" @click="appStore.toggleSidebar">

              <AppLogo :size="22" />

            </button>

            <div v-if="!isLoginPage && appStore.sidebarOpen" class="mobile-backdrop" @click="appStore.closeSidebar" />

            <div v-if="!isLoginPage" class="app-body">

              <AppSidebar />

              <main class="app-main">

                <router-view />

              </main>

            </div>

            <main v-else class="app-main app-main--full">

              <router-view />

            </main>

          </div>

          <SessionSearchModal />

          <DefaultCredentialPrompt />

        </NNotificationProvider>

      </NDialogProvider>

    </NMessageProvider>

  </NConfigProvider>

</template>



<style scoped lang="scss">

@use '@/styles/variables' as *;



.app-shell {

  display: flex;

  flex-direction: column;

  height: calc(100 * var(--vh));

  width: 100%;

  overflow: hidden;

  background-color: $bg-primary;



  &.has-warning {

    padding-top: 36px;

  }



  &.no-chrome {

    display: block;

  }

}



.app-body {

  display: flex;

  flex: 1;

  min-height: 0;

  overflow: hidden;

}



.app-main {

  flex: 1;

  overflow-y: auto;

  background-color: transparent;

  position: relative;

  z-index: 1;

  min-width: 0;



  &--full {

    height: calc(100 * var(--vh));

  }

}



.mobile-backdrop {

  display: none;

  position: fixed;

  inset: 0;

  background: rgba(0, 0, 0, 0.35);

  backdrop-filter: blur(3px);

  z-index: 999;

}



.hamburger-btn {

  display: none;

  position: fixed;

  top: calc(#{$topbar-height} + 10px);

  left: 12px;

  z-index: 99;

  width: 38px;

  height: 38px;

  border: 1px solid $border-color;

  background: $bg-card;

  border-radius: $radius-sm;

  cursor: pointer;

  align-items: center;

  justify-content: center;

  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);

  transition: all $transition-fast;



  .has-warning & {

    top: calc(36px + #{$topbar-height} + 10px);

  }



  &:hover {

    border-color: $accent-primary;

  }

}



.node-warning-bar {

  position: fixed;

  top: 0;

  left: 0;

  width: 100%;

  z-index: 200;

  padding: 8px 16px;

  font-size: 13px;

  font-weight: 600;

  color: #ffffff;

  background: linear-gradient(90deg, #2563eb, #0891b2);

  border-bottom: 1px solid rgba(0, 0, 0, 0.1);

  text-align: center;

  line-height: 1.4;

}



@media (max-width: $breakpoint-mobile) {

  .mobile-backdrop {

    display: block;

  }



  .hamburger-btn {

    display: flex;

  }

}

</style>

