<script setup lang="ts">
// No layout
definePageMeta({
  layout: false,
});

// interfaces
interface currentNavBarInterface {
  name: string;
  icon: string;
  action: any;
  flash: boolean;
  windowAssociated: string;
}

interface associAppWindowInterface {
  name: string;
  id: string;
  title: string;
  component: any;
}

// Import plugins
import { gsap } from "gsap";
import { TextPlugin } from "gsap/TextPlugin";
import { createApp } from "vue";
gsap.registerPlugin(TextPlugin);

// Import Windows
import LoginWindow from "~/components/app/windows/login.vue";
import HotNewsWindow from "~/components/app/windows/hotnews.vue";
import SourcesWindow from "~/components/app/windows/sources.vue";
import AboutWindow from "~/components/app/windows/about.vue";
import ChatbotWindow from "~/components/app/windows/chatbot.vue";
import Error404Window from "~/components/app/windows/error404.vue";

// Icons
import {
  ComputerDesktopIcon,
  UserIcon,
  LanguageIcon,
  ChevronRightIcon,
} from "@heroicons/vue/24/outline";

// i18n
const { t, locale, locales } = useI18n();
const switchLocalePath = useSwitchLocalePath();
const localePath = useLocalePath();

// Router
const router = useRouter();
const route = useRoute();

// values
const popMessage = ref(null);
const menuOpen = ref(false);
const langMenuOpen = ref(false);
const lang = ref(locale.value);
const alertOpen = ref(false);
const currentNavBar = ref<currentNavBarInterface[]>([]);
const bootingAnimation = ref(true);
const activeWindows = ref<associAppWindowInterface>([]);
const openApp = ref();
const openAppId = ref();
const openAppNameQuery = ref();
const currentOpenAppId = ref(0);
const progress = ref(0);
const titleAppName = ref("Desktop");

// Key Data
const menuItems = [
  { name: t("app.hotnews"), windowName: "hotnews" },
  { name: t("app.news"), windowName: "news" },
  { name: t("app.sources"), windowName: "sources" },
  { name: t("app.starred"), windowName: "starred" },
  { name: t("app.chatbot"), windowName: "chatbot" },
  { name: t("app.about"), windowName: "about" },
  { name: t("app.settings"), windowName: "settings" },
  { name: t("app.login"), windowName: "login" },
  { name: t("app.leave"), windowName: "leave" },
];

const associAppWindow = [
  {
    name: "hotnews",
    id: "1",
    title: t("app.hotnews"),
    component: HotNewsWindow,
    width: "700px",
    height: "500px",
  },
  {
    name: "login",
    id: "2",
    title: t("app.login"),
    component: LoginWindow,
  },
  {
    name: "sources",
    id: "3",
    title: t("app.sources"),
    component: SourcesWindow,
  },
  {
    name: "about",
    id: "4",
    title: t("app.about"),
    component: AboutWindow,
  },
  {
    name: "settings",
    id: "5",
    title: t("app.settings"),
    component: Error404Window,
  },
  {
    name: "news",
    id: "6",
    title: t("app.news"),
    component: Error404Window,
  },
  {
    name: "starred",
    id: "7",
    title: t("app.starred"),
    component: Error404Window,
  },
  {
    name: "chatbot",
    id: "8",
    title: t("app.chatbot"),
    component: ChatbotWindow,
    width: "400px",
    height: "600px",
  },
  {
    name: "error404",
    id: "9",
    title: t("app.error404"),
    component: Error404Window,
  },
];

// Date
const currentDate = ref(
  new Date().toLocaleDateString("zh-TW", {
    month: "2-digit",
    day: "2-digit",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit",
    hour12: false,
  }),
);
onMounted(() => {
  setInterval(() => {
    currentDate.value = new Date().toLocaleDateString("zh-TW", {
      month: "2-digit",
      day: "2-digit",
      year: "numeric",
      hour: "2-digit",
      minute: "2-digit",
      second: "2-digit",
      hour12: false,
    });
  }, 1000);
});

// functions
const openWindow = (windowName?: string) => {
  if (windowName === "leave") {
    router.push(localePath("/home"));
  } else {
    if (windowName) findAndOpenWindow(windowName);
  }
  menuOpen.value = false;
};

const unMinWindow = (windowName?: string) => {
  console.log(windowName);
};

// menus
const toggleMenu = () => {
  menuOpen.value = !menuOpen.value;
};
// Lang Menu
const toggleLangMenu = () => {
  langMenuOpen.value = !langMenuOpen.value;
};

// ?openapp= component
onMounted(async () => {
  openApp.value = route.query.openapp;
  openAppId.value = route.query.id;
  if (openApp.value) {
    openWindow(openApp.value);
  }
});

const findAndOpenWindow = (windowName: string) => {
  const app = associAppWindow.find((app) => app.name === windowName);

  // Prevent dual logins
  if (
    windowName === "login" &&
    activeWindows.value.some((window) => window.name === "login")
  ) {
    return;
  }

  // Prevent dual about
  if (
    windowName === "about" &&
    activeWindows.value.some((window) => window.name === "about")
  ) {
    return;
  }

  if (app) {
    // Use shallowRef for better performance with components
    const windowComponent = shallowRef(app.component);
    titleAppName.value = app.title;

    activeWindows.value.push({
      id: currentOpenAppId.value,
      component: windowComponent,
      name: windowName,
      title: app.title,
      width: app.width || "400px",
      height: app.height || "300px",
    });
    currentOpenAppId.value++;
  }
};

const obtainTopWindowPosition = (windowId: string) => {
  const windowIndex = activeWindows.value.findIndex(
    (window) => window.id === windowId,
  );
  console.log(windowIndex);
  if (windowIndex !== -1) {
    const [window] = activeWindows.value.splice(windowIndex, 1);
    activeWindows.value.push(window);
  }
};

const closeWindow = (windowId: string) => {
  activeWindows.value = activeWindows.value.filter(
    (window) => window.id !== windowId,
  );
  console.log("activeWindows.value", activeWindows.value);
};

const maxWindow = (windowId: string) => {};

// Title
useSeoMeta({
  title: titleAppName.value + " - Desktop",
});

// Booting animation
onMounted(() => {
  // booting animation bypass
  const bootingHeaderParams = route.query.bypass;
  if (bootingHeaderParams) {
    bootingAnimation.value = false;
    return;
  }
  if (bootingAnimation.value) {
    gsap.to(popMessage.value, {
      duration: 0.5,
      text: t("app.booting"),
      ease: "none",
    });
    setTimeout(() => {
      bootingAnimation.value = false;
    }, 2000);
  }
});

watchEffect((cleanupFn) => {
  const timer = setTimeout(() => (progress.value = 100), 500);
  cleanupFn(() => clearTimeout(timer));
});
</script>
<template>
  <div v-if="bootingAnimation">
    <div
      class="flex flex-col justify-center align-center text-center absolute w-full h-screen inset-0"
    >
      <Progress
        v-model="progress"
        class="w-3/5 absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
      />
      <br />
      <span class="text-xl text-bold mt-3"
        >Launching your fancy desktop...</span
      >
    </div>
  </div>
  <div
    class="absolute inset-x-0 flex flex-row px-2 py-1 bg-[#7D7C7C]/70 text-white justify-between align-center text-center z-50"
    v-else
  >
    <!--Menu container-->
    <div class="flex flex-row g-2 text-gray-400 text-white z-9999">
      <button
        @click="toggleMenu"
        class="w-8 h-8 text-white hover:text-blue-500 transition-all duration-100 flex flex-row"
      >
        <ComputerDesktopIcon />
      </button>
      <span class="ml-1 mr-2 text-[20px]">|</span>
      <!--navbar icons for min and max application window-->
      <button
        class="flex flex-row items-center gap-x-2 text-gray-400 hover:text-gray-600 transition-all duration-100"
      ></button>
      <div
        v-for="item in currentNavBar"
        :key="item.name"
        class="flex flex-row items-center gap-x-2 hover:bg-gray-100 transition-all duration-100 px-4 py-2 cursor-pointer"
      >
        <button
          @click="unMinWindow(item.windowAssociated)"
          class="flex flex-row items-center gap-x-2 text-gray-400 hover:text-gray-600 transition-all duration-100"
        >
          <span>{{ item.name }}</span>
          <span
            v-if="item.flash"
            class="animate-ping absolute inline-flex h-3 w-3 rounded-full bg-red-400 opacity-75"
          ></span>
          <span v-if="item.icon" :class="item.icon"> </span>
        </button>
      </div>
    </div>
    <div class="flex flex-row gap-5">
      <button
        class="p-1 hover:text-blue-200 transition-all duration-100 hover:bg-gray-500 rounded"
        @click="toggleLangMenu"
      >
        {{ t("localeflag") }}
      </button>
      <div class="text-center align-middle justify-center text-white">
        {{ currentDate }}
      </div>
    </div>
  </div>
  <div class="w-full h-[2.5em]"></div>
  <!--Menu-->
  <Transition
    enter-active-class="animate__animated animate__fadeInDown animate_fast03"
    leave-active-class="animate__animated animate__fadeOutUp animate_fast03"
  >
    <div
      class="m-2 p-2 bg-gray-800 shadow-lg w-fit rounded-[10px] v-9998"
      v-if="menuOpen"
    >
      <div v-for="item in menuItems" :key="item.name" class="">
        <button
          @click="openWindow(item.windowName)"
          class="flex flex-row items-center gap-x-2 text-gray-400 hover:text-gray-600 transition-all duration-100"
        >
          <span>{{ item.name }}</span>
          <ChevronRightIcon class="w-4 h-4 justify-center align-center" />
        </button>
      </div>
    </div>
  </Transition>
  <Transition
    enter-active-class="animate__animated animate__fadeInDown animate_fast03"
    leave-active-class="animate__animated animate__fadeOutUp animate_fast03"
  >
    <div v-if="langMenuOpen">
      <div
        class="w-48 bg-white rounded-md shadow-lg py-1 flex flex-col gap-y-5"
      >
        <a
          v-for="loc in availableLocales"
          :key="loc.code"
          :href="switchLocalePath(loc.code)"
          v-on:click="langMenuOpen = false"
          class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 transition-all duration-100"
        >
          {{ loc.name || loc.code }}
        </a>
      </div>
    </div>
  </Transition>
  <!--Main desktop contents-->
  <div
    class="flex flex-col justify-center align-center text-center absolute w-full h-screen inset-x-0 inset-y-0 z-[-10]"
    id="desktop"
  ></div>
  <Transition>
    <div>
      <DraggableWindow
        v-for="window in activeWindows"
        :key="window.id"
        :title="window.title"
        @close="closeWindow(window.id)"
        @min="unMinWindow(window.id)"
        :width="window.width"
        :height="window.height"
        @click="obtainTopWindowPosition(window.id)"
        @maximize="maxWindow(window.id)"
      >
        <Suspense>
          <Component
            :is="window.component"
            @error="console.error('Error:', $event)"
          />
        </Suspense>
      </DraggableWindow>
    </div>
  </Transition>
</template>
