<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'

import { getCurrentRoute } from 'src/utilities/vuetils'
import { injectStylesheet } from 'src/utilities/dom'
import { storage } from './utilities/fetch'
import { useRouteStore } from 'src/routes'

import type { Link, RoutedWindow, WarningModal } from '@goldenwere/static-web-templates-types'

import HeaderLink from 'src/components/shared/header-link.vue'
import ThemePicker from 'src/components/shared/theme-picker.vue'
import WarningPrompt from 'src/components/shared/warning-prompt.vue'

declare const window: RoutedWindow

const router = useRouter()
const routeStore = useRouteStore()
const globalConfig = routeStore._globals

let currentRoute = getCurrentRoute()
let routeConfig = routeStore._routes[currentRoute.path]
let rememberWarning = false

const ready = ref(false)
const firstInit = ref(false)
const acknowledged = ref(false)
const storageId = ref('')
const routeId = ref('')
const warning = ref({} as WarningModal)
const breadcrumbs = computed({
  get() { return routeStore._breadcrumbs },
  set() {}
})

const determineWarning = () => {
  if (!routeConfig.warning || routeStore.doesRouteRememberWarning(currentRoute.path)) {
    acknowledged.value = true
    return
  }
  rememberWarning = storage.read(`${storageId.value}::rememberWarning`) || false
  if (rememberWarning) {
    acknowledged.value = true
    routeStore.rememberRouteWarning(currentRoute.path)
    return
  }
  warning.value = routeConfig.warning === true 
    ? globalConfig.warning
    : routeConfig.warning
}

const determineStylesheets = (stylesheetUrls?: string[]) => {
  const staleStylesheets = document.head.querySelectorAll('link.page-stylesheet[rel="stylesheet"]')
  staleStylesheets.forEach(stylesheet => {
    document.head.removeChild(stylesheet)
  })

  stylesheetUrls?.forEach(stylesheet => {
    injectStylesheet(stylesheet, 'page-stylesheet')
  })
}

const determineGlobalStylesheets = () => {
  globalConfig.stylesheetUrls.forEach(stylesheet => {
    injectStylesheet(stylesheet, 'global-stylesheet')
  })
}

const determineScript = async () => {
  if (!!routeConfig.scriptUrl) {
    const { callbacks } = await import(/* @vite-ignore */ routeConfig.scriptUrl)
    if (!!callbacks.onPageLoaded) {
      callbacks.onPageLoaded();
    }
  }

  return null
}

const refresh = async () => {
  ready.value = false
  acknowledged.value = false
  currentRoute = getCurrentRoute()
  routeConfig = routeStore._routes[currentRoute.path]
  storageId.value = `${globalConfig.id}::${currentRoute.path}`
  routeId.value = routeStore._routes[currentRoute.path].id

  window.routeConfig = {...routeConfig}
  routeStore.setBreadcrumbs(currentRoute)

  determineWarning()
  determineStylesheets(routeConfig.stylesheetUrls)
  scrollTo({
    top: 0,
  })

  setTimeout(() => ready.value = true)
}

const onAcknowledgedWarning = () => {
  acknowledged.value = true
  routeStore.rememberRouteWarning(currentRoute.path)
}

const onRouteLoaded = async () => {
  await determineScript()
}

const handlePageClosed = async (scriptUrl?: string) => {
  if (!!scriptUrl) {
    const { callbacks } = await import(/* @vite-ignore */ scriptUrl)
    if (!!callbacks.onPageClosed) {
      callbacks.onPageClosed()
    }
  }
}

onMounted(async () => {
  await refresh()
  firstInit.value = true
  determineGlobalStylesheets()
  router.afterEach(async (to, from) => {
    const oldUrl = routeConfig.scriptUrl
    await refresh()
    await handlePageClosed(oldUrl)
  })
})
</script>

<template lang="pug">
#main-container
  header(
    v-if='firstInit && !!globalConfig.header'
  )
    nav#header-nav
      ul
        HeaderLink(
          v-for='entry in globalConfig.header'
          :entry='entry'
        )
    nav#header-breadcrumb(
      v-if='breadcrumbs.length > 0'
    )
      span.breadcrumb(
        v-for='(breadcrumb, i) in breadcrumbs'
      )
        span(
          v-if='breadcrumbs.length === 1 || i === breadcrumbs.length - 1'
        ) {{ breadcrumb.caption }}
        span(
          v-else
        )
          router-link(
            :to='{ path: breadcrumb.href }'
          ) {{ breadcrumb.caption }}
          span /
    #header-controls
      ThemePicker
  main(
    v-if='ready'
  )
    #main-entry(
      v-if='acknowledged'
    )
      router-view(
        v-slot='{ Component }'
        @loaded='onRouteLoaded'
      )
        Transition
          component(
            :id='routeId'
            :is='Component'
          )
    #main-entry(
      v-else
    )
      Transition
        WarningPrompt(
          :storageId='storageId'
          :warning='warning'
          @acknowledged='onAcknowledgedWarning()'
        )
</template>

<style scoped lang="sass">

</style>
