<template>
  <main :class='[
    "w-full", "h-full", "large:px-8",
    "flex", "justify-center", "flex-1",
    "bg-(--bg-color)", "text-(--text-color)",
  ]'>
    <ErrorMsg :error="error" />

    <div id="alert-container" class="z-9995" />

    <Progress
      :class='[
        "fixed", "inset-0", "z-9999",
        "left-auto", "top-2", "right-2",
      ]'
      :size="6"
      v-if="routerStatus.isLoad"
    />

    <Suspense>
      <RouterView
        :key="route.fullPath"
      />
    </Suspense>
    
    <RouterLink
      class="max-large:hidden fixed top-auto bottom-1"
      to="/about/ulc"
    >
      uwuzu Light Client {{ release?.version ?? "" }}
    </RouterLink>
  </main>
</template>

<script lang="ts" setup>
import { onMounted, onBeforeUnmount, ref, Suspense } from "vue";
import { RouterView, useRoute } from "vue-router";
import Database, { getByIndex } from "@/lib/db";
import ErrorMsg from "@/components/Window/ErrorMsg.vue";
import { isSignin } from "@/lib/account";
import Progress from "@/components/Progress.vue";
import routerStatus from "@/lib/router";
import { network } from "@/layouts/Layout.vue";
import { release } from "@/main";

const route = useRoute();

const error = ref<any>();
const customStyle = ref<HTMLStyleElement>();

function handleError(event: ErrorEvent | PromiseRejectionEvent) {
  error.value = event instanceof PromiseRejectionEvent
    ? event.reason
    : event;
}

function handleOnline() {
  network.isOnline = true;
}

function handleOffline() {
  network.isOnline = false;
}

onMounted(async () => {
  window.addEventListener("error", handleError);
  window.addEventListener("unhandledrejection", handleError);
  
  window.addEventListener("online", handleOnline);
  window.addEventListener("offline", handleOffline);

  if ("serviceWorker" in navigator) {
    const swFile = import.meta.env.MODE === "production"
      ? "/sw.js"
      : "/dev-sw.js?dev-sw";
    
    navigator.serviceWorker.register(swFile, {
      type: import.meta.env.MODE === "production" ? "classic" : "module",
      scope: "/",
    });
  }

  const db = new Database();
  try {
    await db.open();
    await isSignin(db);
  } catch (err) {
    error.value = err;
  }
  const customcssRow = await getByIndex(db.settings, "name", "customcss");
  
  if (typeof customcssRow?.value === "string") {
    const style = document.createElement("style");
    style.id = "customcss";
    style.textContent = customcssRow.value;
    document.head.appendChild(style);
    customStyle.value = style;
  }
});

onBeforeUnmount(() => {
  window.removeEventListener("error", handleError);
  window.removeEventListener("unhandledrejection", handleError);
  
  window.removeEventListener("online", handleOnline);
  window.removeEventListener("offline", handleOffline);
  
  if (customStyle.value) {
    document.head.removeChild(customStyle.value);
  }
});
</script>