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

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

interface associAppWindowInterface {
  name: string;
  id: string;
  absoluteId: string;
  title: string;
  component: any;
  width: string;
  height: string;
  black: boolean;
  translatable: boolean;
  translateState: boolean;
}

interface minAppWindowInterface {
  name: string;
  id: string;
  absoluteId: string;
  title: string;
  component: any;
  width: string;
  height: string;
  black: boolean;
  translatable: boolean;
  lastpositionw: string;
  lastpositionh: string;
}

// Import plugins
import { v4 as uuidv4 } from "uuid";
import { gsap } from "gsap";
import confetti from "js-confetti";
import translate from "translate";

// Import Windows
import UserWindow from "~/components/app/windows/user.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 AboutNewsOrgWindow from "~/components/app/windows/aboutNewsOrg.vue";
import TTYWindow from "~/components/app/windows/tty.vue";
import FavStaredWindow from "~/components/app/windows/fav.vue";
import NewsWindow from "~/components/app/windows/news.vue";
import NewsViewWindow from "~/components/app/windows/newsView.vue";
import SettingsWindow from "~/components/app/windows/settings.vue";
import PrivacyPolicyWindow from "~/components/app/windows/privacypolicy.vue";
import TOSWindow from "~/components/app/windows/tos.vue";
import onBoardingWindow from "~/components/app/windows/onBoarding.vue";

// Import Icons
import {
  ComputerDesktopIcon,
  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);
2;
const currentNavBar = ref<currentNavBarInterface[]>([]);
const bootingAnimation = ref(true);
const activeWindows = ref<associAppWindowInterface[]>([]);
const hiddenWindows = ref<minAppWindowInterface[]>([]);
const openApp = ref();
const openAppId = ref();
const openAppNameQuery = ref();
const currentOpenAppId = ref(0);
const progress = ref(0);
const titleAppName = ref("Desktop");
const openingAppViaAnApp = ref(false);
const passedValues = ref();
const globalWindowVal = ref(new Map());
const changeLangAnimation = ref(false);
const applyForTranslation = ref(false);
const langPrefDifferent = ref(false);
const notLoggedInState = ref(false);
const translateProvider = ref("");

// Key Data
const menuItems = [
  { 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.terminal"), windowName: "tty" },
  { name: t("app.settings"), windowName: "settings" },
  { name: t("app.leave"), windowName: "leave" },
];

const associAppWindow = [
  {
    name: "login",
    id: "2",
    title: t("app.login"),
    component: UserWindow,
    translatable: false,
  },
  {
    name: "sources",
    id: "3",
    title: t("app.sources"),
    component: SourcesWindow,
    width: "700px",
    height: "500px",
    translatable: true,
  },
  {
    name: "about",
    id: "4",
    title: t("app.about"),
    component: AboutWindow,
    translatable: true,
  },
  {
    name: "settings",
    id: "5",
    title: t("app.settings"),
    component: SettingsWindow,
    translatable: false,
  },
  {
    name: "news",
    id: "6",
    title: t("app.news"),
    component: NewsWindow,
    width: "800px",
    height: "600px",
    translatable: true,
  },
  {
    name: "starred",
    id: "7",
    title: t("app.starred"),
    component: FavStaredWindow,
    translatable: true,
  },
  {
    name: "chatbot",
    id: "8",
    title: t("app.chatbot"),
    component: ChatbotWindow,
    width: "400px",
    height: "600px",
    translatable: false,
  },
  {
    name: "aboutNewsOrg",
    id: "9",
    title: t("app.aboutNewsOrg"),
    component: AboutNewsOrgWindow,
    translatable: true,
  },
  {
    name: "tty",
    id: "10",
    title: t("app.terminal"),
    component: TTYWindow,
    black: true,
    translatable: false,
  },
  {
    name: "newsView",
    id: "11",
    title: t("app.newsview"),
    component: NewsViewWindow,
    translatable: true,
  },
  {
    name: "privacypolicy",
    id: "12",
    title: t("app.privacypolicy"),
    component: PrivacyPolicyWindow,
    translatable: false,
  },
  {
    name: "tos",
    id: "13",
    title: t("app.tos"),
    component: TOSWindow,
    translatable: false,
  },
  {
    name: "onboard",
    id: "14",
    title: "OnBoarding",
    component: onBoardingWindow,
    translatable: false,
  },
];

// OnBoarding
// Feedback from: https://hackclub.slack.com/archives/C090DPG6681/p1749303838738019
const currentStep = ref(0);
const showOnboarding = ref(true);
onMounted(() => {
  showOnboarding.value = !localStorage.getItem("onboardingComplete");
});
const nextStep = () => {
  currentStep.value++;
};
const finishOnboarding = () => {
  showOnboarding.value = false;
  localStorage.setItem("onboardingComplete", "true");
};
/*const onBoarding = [
  {
    step: 0,
    point: "none",
    text: "Hi! Welcome to the news analyze desktop enviroment!",
    buttons: [
      "bypass": nextStep,
      "contuine": nextStep
    ]
  },
  {
    step: 1,
    point: "top-left",
    text: "Click here to open applications",
    buttons: [
      "ok": nextStep
    ]
  },
  {
    step: 2,
    point: "left-navbar-1",
    text: "Click here to open the news window",
    buttons: [
      "ok": nextStep
    ]
  },
  {
    step: 3,
    point: "center",
    text: "Click here open a news article",
    buttons: [
      "ok": nextStep
    ]
  },
  {
    step: 4,
    point: "center-close-translate-left",
    text: "Click here to translate the page.",
    buttons: [
      "ok": nextStep
    ]
  },
  {
    step: 5,
    point: "center-close-x-left",
    text: "Click here to close the window",
    buttons: [
      "ok": nextStep
    ]
  },
  {
    step: 6,
    point: "more-top-right-3",
    text: "Click here to change the app's language. (YOU WILL LOSE ALL YOUR WINDOWS)",
    buttons: [
      "ok": nextStep
    ]
  },
  {
    step: 7,
    point: "none",
    text: "That's it, welcome! If you want to learn more, you can go to yhw.tw/newsanalyzedocs.",
    buttons: [
      "ok": finishOnboarding
    ]
  },
  ];*/

// Confeti
const successcanvas = ref();
const confetiActive = ref(false);
const successpop = ref<any>();
onMounted(() => {
  successpop.value = new confetti();
});

// 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
onMounted(() => {
  associAppWindow.forEach((window) => {
    globalWindowVal.value.set(window.name, {
      id: window.id,
      title: window.title,
      windowCount: 1,
    });
  });
});

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

const unMinWindow = (windowName?: string) => {
  hiddenWindows.value = hiddenWindows.value.filter(
    (window) => window.name !== windowName,
  );
  console.log(windowName);
};

// menus
const toggleMenu = () => {
  menuOpen.value = !menuOpen.value;
};

// ?openapp= component
onMounted(async () => {
  openApp.value = route.query.openapp;
  openAppId.value = route.query.id;
  if (openApp.value) {
    // DO NOT REMOVE THIS FUNCTION!! IT WILL ABSOLUTELY 100% FAIL!
    if (openApp.value === "newsView") {
      return;
    }
    setTimeout(() => {
      openWindow(openApp.value);
    }, 2000);
  }
});

const navBarDisplayText = (text: string) => {
  if (!text) {
    return;
  }
  const trimSpaces = text.trim();
  const regex = /.{0,7}/;
  if (trimSpaces.length <= 7) {
    return text;
  }
  const maxStay = text.match(regex);
  const filterToMax7Chars = maxStay[0] + "...";
  return filterToMax7Chars;
};

const findAndOpenWindow = (windowName: string, windowTitle?: 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;
    const abosluteId = uuidv4();
    activeWindows.value.push({
      id: currentOpenAppId.value,
      absoluteId: abosluteId,
      component: windowComponent,
      name: windowName,
      title: windowTitle || app.title,
      width: app.width || "600px",
      height: app.height || "400px",
      black: app.black || false,
      translatable: app.translatable || false,
    });
    currentOpenAppId.value++;
    // Add to navbar
    const windowNameVal2 =
      globalWindowVal.value.get(windowName).windowCount === 1
        ? navBarDisplayText(app.title)
        : navBarDisplayText(app.title) +
          "(" +
          globalWindowVal.value.get(windowName).windowCount +
          ")";
    currentNavBar.value.push({
      name: navBarDisplayText(windowTitle) || windowNameVal2,
      icon: "anything",
      action: "idk",
      flash: true,
      windowAssociated: abosluteId,
      minimized: false,
    });
    globalWindowVal.value.get(windowName).windowCount++;
  }
};

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

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

const openNewWindowViaApp = (windowId: string) => {
  openingAppViaAnApp.value = true;
  findAndOpenWindow(windowId);
  setTimeout(() => {
    openingAppViaAnApp.value = false;
  }, 1000);
};

const toggleMinWindow = (windowUUId: string) => {
  const windowInfo = currentNavBar.value.find(
    (item) => item.windowAssociated === windowUUId,
  );
  const activeWindow = activeWindows.value.find(
    (window) => window.absoluteId === windowUUId,
  );
  // Add logic to store hidden windows.
  if (windowInfo && activeWindow) {
    hiddenWindows.value.push({
      id: activeWindow.id,
      absoluteId: activeWindow.absoluteId,
      component: activeWindow.component,
      name: activeWindow.name,
      title: activeWindow.title,
      width: activeWindow.width,
      height: activeWindow.height,
      black: activeWindow.black || false,
      translatable: activeWindow.translatable || false,
      lastpositionw: "",
      lastpositionh: "",
    });
    //activeWindows.value = activeWindows.value.filter(window => window.absoluteId !== windowUUId);
  }
  console.log(hiddenWindows.value);
};

// Title
useSeoMeta({
  title: "Desktop",
});

watchEffect(() => {
  useSeoMeta({
    title: titleAppName.value + " - Desktop",
  });
});
// Booting animation
onMounted(() => {
  const changeLang = route.query.changelang;
  if (changeLang) {
    bootingAnimation.value = false;
    changeLangAnimation.value = true;
  }
  setTimeout(() => {
    changeLangAnimation.value = false;
  }, 4000);
});

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

// Loading Effect.
watchEffect((cleanupFn) => {
  const tier = setTimeout(() => (progress.value = 10), Math.random() * 50);
  const timer = setTimeout(() => (progress.value = 30), Math.random() * 100);
  const timmer = setTimeout(() => (progress.value = 70), Math.random() * 150);
  const timmmer = setTimeout(() => (progress.value = 100), 1800);
  cleanupFn(() => clearTimeout(tier));
  cleanupFn(() => clearTimeout(timer));
  cleanupFn(() => clearTimeout(timmer));
  cleanupFn(() => clearTimeout(timmmer));
});

const openArticles = async (slug: string, titleName?: string) => {
  openingAppViaAnApp.value = true;
  passedValues.value = slug;
  var titleNameFinal = "";
  if (titleName) {
    titleNameFinal = titleName + "  " + t("app.newsview");
  } else {
    titleNameFinal = t("app.newsview");
  }
  console.log(titleName);
  findAndOpenWindow("newsView", titleName);
  console.log("t2: " + titleName);
  setTimeout(() => {
    openingAppViaAnApp.value = false;
    passedValues.value = null;
    console.log("wiping values");
  }, 1000);
};

const openNewsSourcePage = async (slug: string, title: string) => {
  openingAppViaAnApp.value = true;
  passedValues.value = slug;
  const titleNameFinal = title ? "關於" + title : t("app.aboutNewsOrg");
  findAndOpenWindow("aboutNewsOrg", titleNameFinal);

  setTimeout(() => {
    openingAppViaAnApp.value = false;
    passedValues.value = null;
  }, 1000);
};
const toggleTranslate = (windowId: string) => {
  const windowIndex = activeWindows.value.findIndex((w) => w.id === windowId);
  if (windowIndex !== -1) {
    activeWindows.value[windowIndex].translateState =
      !activeWindows.value[windowIndex].translateState;
  }
};

const translateAvailable = () => {};

// Load user config via HTTP requests to the server.
/*
onMounted(async () => {
  const loadUserInfoData = await loadUserInfo();
  if (!loadUserInfoData.user) {
    notLoggedInState.value = true;
  }
  if (
    loadUserInfoData.langPref !== locale &&
    langPrefDifferent.doNotShowLangPrefPopUp === false
  ) {
    langPrefDifferent.value = true;
  }
  if (locale === "en" && loadUserInfoData.translate.enabled === true) {
    applyForTranslation.value = true;
  }
  // Use Google as the default translate provider
  translateProvider.value = loadUserInfoData.translate.provider || "google";
  console.log(langPrefDifferent);
  });*/
</script>
<template>
  <div v-if="changeLangAnimation">
    <div
      class="flex flex-col justify-center align-center text-center absolute w-full h-screen inset-0 overscroll-none bg-gray-600/50 z-[999999]"
    >
      <span>{{ t("app.changelangmessage") }}</span>
    </div>
  </div>
  <div v-if="bootingAnimation">
    <div
      class="flex flex-col justify-center align-center text-center absolute w-full h-screen inset-0 overscroll-none"
    >
      <Progress
        v-model="progress"
        class="w-3/5 absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
      />
      <!--Spacing for Firefox Users-->
      <div class="p-2"></div>
      <span class="text-xl text-bold mt-3">{{ t("app.launchtext") }}</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 overscroll-none"
    v-else
  >
    <!--Menu container-->
    <div
      class="flex flex-row g-2 rounded-xl gray-500/80 backdrop-blur-sm z-9999 selection:opacity-0"
    >
      <button
        @click="toggleMenu"
        class="w-8 h-8 text-white hover:text-blue-500 transition-all duration-100 flex flex-row"
      >
        <ComputerDesktopIcon />
      </button>
      <!--DO NOT MODIFY THE CLASSES OF THIS |, THIS COULD WORK OR BRAKE I HAVE NO CLUE WHY DOES IT DO THAT, BUT DON'T DO IT.-->
      <span class="ml-1 mr-2 text-[20px]">|</span>
      <!--navbar icons for min and max application window-->
      <div
        class="overflow-hidden overflow-x-auto overflow-y-hidden scrollbar-thin scrollbar-track-transparent scrollbar-thumb-white flex-nowrap whitespace-nowrap min-w-0"
      >
        <div class="flex flex-row flex-shrink-0 min-w-0">
          <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-150 px-4 py-1 cursor-pointer group rounded-xl"
          >
            <button
              @click="toggleMinWindow(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>
            </button>
          </div>
        </div>
      </div>
    </div>
    <div class="flex flex-row gap-5">
      <NuxtLink :to="localePath('/desktop?changelang=1', t('nextlang'))">
        <button
          class="p-1 hover:text-blue-200 transition-all duration-100 hover:bg-gray-500 rounded selection:opacity-0"
        >
          {{ t("localeflag") }}
        </button>
      </NuxtLink>
      <div
        class="text-center align-middle justify-center text-white selection:opacity-0 hover:cursor-default"
      >
        {{ 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 selection:opacity-0"
      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>
  <!--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>
  <!--Detect langPref different popup-->
  <Dialog v-model:open="langPrefDifferent">
    <DialogContent class="!border-0 !bg-black !rounded">
      <DialogHeader>
        <DialogTitle>{{ t("settings.logout") }}</DialogTitle>
        <DialogDescription>
          {{ t("popuptext.logout") }}
        </DialogDescription>
      </DialogHeader>
      <DialogFooter>
        <Button
          @click="
            () => {
              langPrefDifferent.value = false;
            }
          "
          variant="outline"
        >
          {{ t("popup.stay") }}
        </Button>
        <Button @click="() => switchLocalePath()" variant="outline">
          {{ t("popup.change") }}
        </Button>
      </DialogFooter>
    </DialogContent>
  </Dialog>
  <!--Window system-->
  <Transition>
    <div>
      <DraggableWindow
        v-for="window in activeWindows"
        :key="window.id"
        :title="window.title"
        @close="closeWindow(window.id, window.absoluteId)"
        @min="unMinWindow(window.id)"
        :width="window.width"
        :height="window.height"
        @click="obtainTopWindowPosition(window.id)"
        :black="window.black"
        @translate="() => toggleTranslate(window.id)"
        :notLoggedInState="notLoggedInState"
        :windowTranslateState="window.translatable"
      >
        <Suspense>
          <Component
            :is="window.component"
            @error="console.error('Error:', $event)"
            @windowopener="openNewWindowViaApp($event)"
            @loadValue=""
            @openArticles="openArticles"
            @openNewsSourcePage="openNewsSourcePage"
            :values="passedValues"
            :windows="activeWindows"
            @closeWindow="closeWindow"
            :applyForTranslation="window.translateState"
            :windowTranslateState="window.translatable"
            :notLoggedInState="notLoggedInState"
          />
        </Suspense>
      </DraggableWindow>
    </div>
  </Transition>
  <div v-if="confetiActive">
    <div v-ref="successcanvas"></div>
  </div>
</template>