<template>
  <nav id="nav_bar" class="bg-neutral-700">
    <div
      class="mx-auto px-4"
      :class="[showNavbarBreadcrumb ? 'min-h-12' : 'h-12']"
    >
      <div
        class="flex justify-between items-center flex-wrap relative"
        v-show="showNavbarBreadcrumb"
      >
        <div id="nav_bar_logged_in" class="flex flex-1 items-center">
          <!-- Back to Files page -->
          <router-link to="/files" class="mr-4" v-if="showIcon" id="backPage">
            <span
              class="material-symbols-outlined text-neutral-10 !leading-loose"
            >
              arrow_back
            </span>
          </router-link>
          <div>
            <h2
              v-if="navViewName !== 'UPLOAD'"
              class="mr-14 py-3 text-2xl font-black text-neutral-10"
            >
              {{ navViewName }}
            </h2>
            <h2 v-else class="mr-14 py-3 text-2xl font-black text-neutral-10">
              FILES
            </h2>
          </div>
          <ul
            class="flex justify-center items-center space-x-4 text-xl font-semibold text-neutral-300 cursor-pointer"
          >
            <li
              @click="onNavItemBtnClick($event, item)"
              v-for="(item, index) in navViewData[navViewName]"
              :key="index"
              class="nav-item"
              :class="{ active: activePage === item }"
            >
              {{ item }}
            </li>
          </ul>
        </div>
        <!-- Files Page: Search and Upload -->
        <div
          class="flex justify-end items-center"
          v-if="navViewName === 'FILES'"
        >
          <div
            id="import_btn"
            class="btn btn-sm btn-neutral cursor-pointer"
            @click="uploadModal = true"
          >
            Import
            <UploadModal
              :visible="uploadModal"
              @closeModal="uploadModal = $event"
            ></UploadModal>
          </div>
        </div>
        <!-- Upload, Performance, Compare have no button actions -->
        <div v-else-if="noShowSaveButton"></div>
        <!-- Other Page: Save and Download -->
        <!-- Save: if data exists, prompt rename; if no data, prompt save; if unchanged, do nothing -->
        <div v-else class="space-x-4">
          <button
            class="btn btn-sm"
            :class="[disabledSave ? 'btn-disable' : 'btn-neutral']"
            :disabled="disabledSave"
            @click="saveModal"
          >
            Save
          </button>
        </div>
        <AcctMenu v-if="showNavbarBreadcrumb" />
      </div>
    </div>
  </nav>
</template>
<script setup>
// The Lucia project.
// Copyright 2023-2026 DSP, inc.  All rights reserved.
// Authors:
//   chiayin.kuo@dsp.im (chiayin), 2023/1/31
//   cindy.chang@dsp.im (Cindy Chang), 2024/5/30
//   imacat.yang@dsp.im (imacat), 2023/9/23
/**
 * @module components/Navbar Navigation bar with breadcrumb-style
 *   page tabs, import button for Files, and save button for
 *   Map/Conformance pages.
 */

import { ref, computed, watch, onMounted } from "vue";
import { useRoute, useRouter } from "vue-router";
import { storeToRefs } from "pinia";
import emitter from "@/utils/emitter";
import { useFilesStore } from "@/stores/files";
import { useAllMapDataStore } from "@/stores/allMapData";
import { useConformanceStore } from "@/stores/conformance";
import { usePageAdminStore } from "@/stores/pageAdmin";
import { useMapCompareStore } from "@/stores/mapCompareStore";
import {
  saveFilter,
  savedSuccessfully,
  saveConformance,
} from "@/module/alertModal.js";
import UploadModal from "./File/UploadModal.vue";
import AcctMenu from "./AccountMenu/AcctMenu.vue";

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

const store = useFilesStore();
const allMapDataStore = useAllMapDataStore();
const conformanceStore = useConformanceStore();
const mapCompareStore = useMapCompareStore();
const pageAdminStore = usePageAdminStore();

const {
  logId,
  tempFilterId,
  createFilterId,
  filterName,
  postRuleData,
  isUpdateFilter,
} = storeToRefs(allMapDataStore);
const {
  conformanceRuleData,
  conformanceLogId,
  conformanceFilterId,
  conformanceLogTempCheckId,
  conformanceFilterTempCheckId,
  conformanceLogCreateCheckId,
  conformanceFilterCreateCheckId,
  isUpdateConformance,
  conformanceFileName,
} = storeToRefs(conformanceStore);
const {
  activePage,
  pendingActivePage,
  activePageComputedByRoute,
  shouldKeepPreviousPage,
} = storeToRefs(pageAdminStore);
const {
  setPendingActivePage,
  setPreviousPage,
  setActivePage,
  setActivePageComputedByRoute,
  setIsPagePendingBoolean,
} = pageAdminStore;

const showNavbarBreadcrumb = ref(false);
const navViewData = {
  // e.g. FILES: ['ALL', 'DISCOVER', 'COMPARE', 'DESIGN', 'SIMULATION'],
  FILES: ["ALL", "DISCOVER", "COMPARE"],
  // e.g. DISCOVER: ['MAP', 'CONFORMANCE', 'PERFORMANCE', 'DATA']
  DISCOVER: ["MAP", "CONFORMANCE", "PERFORMANCE"],
  // e.g. COMPARE: ['PROCESS MAP', 'DASHBOARD']
  COMPARE: ["MAP", "PERFORMANCE"],
  "ACCOUNT MANAGEMENT": [],
  "MY ACCOUNT": [],
};
const navViewName = ref("FILES");
const uploadModal = ref(false);

const disabledSave = computed(() => {
  switch (route.name) {
    case "Map":
    case "CheckMap":
      // Cannot save without a filter ID or a temporary tempFilterId
      return !tempFilterId.value;
    case "Conformance":
    case "CheckConformance":
      return !(
        conformanceFilterTempCheckId.value || conformanceLogTempCheckId.value
      );
    default:
      return true;
  }
});

const showIcon = computed(() => {
  return !["FILES", "UPLOAD"].includes(navViewName.value);
});

const noShowSaveButton = computed(() => {
  return (
    navViewName.value === "UPLOAD" ||
    navViewName.value === "COMPARE" ||
    navViewName.value === "ACCOUNT MANAGEMENT" ||
    activePage.value === "PERFORMANCE"
  );
});

watch(
  () => route,
  () => {
    getNavViewName();
  },
  { deep: true },
);

/**
 * Handles navigation when a navbar tab is clicked.
 * @param {Event} event - The click event from the nav item.
 */
function onNavItemBtnClick(event) {
  let type;
  let fileId;
  let isCheckPage;
  const navItemCandidate = event.target.innerText;

  setPendingActivePage(navItemCandidate);

  switch (navViewName.value) {
    case "FILES":
      store.filesTag = navItemCandidate;
      break;
    case "DISCOVER": {
      type = route.params.type;
      fileId = route.params.fileId;
      isCheckPage = route.name.includes("Check");
      const discoverRoutes = {
        MAP: "Map",
        CONFORMANCE: "Conformance",
        PERFORMANCE: "Performance",
      };
      const baseName = discoverRoutes[navItemCandidate];
      if (baseName) {
        const routeName = isCheckPage ? `Check${baseName}` : baseName;
        router.push({
          name: routeName,
          params: { type: type, fileId: fileId },
        });
      }
      break;
    }
    case "COMPARE":
      switch (navItemCandidate) {
        case "MAP":
          router.push({
            name: "MapCompare",
            params: mapCompareStore.routeParam,
          });
          break;
        case "PERFORMANCE":
          router.push({
            name: "CompareDashboard",
            params: mapCompareStore.routeParam,
          });
          break;
        default:
          break;
      }
  }
}

/**
 * Determines the navbar view name and active page from the current route.
 * @returns {string} The navigation item name to highlight.
 */
function getNavViewName() {
  const name = route.name;
  let valueToSet;

  if (route.name === "NotFound404" || !route.matched[1]) {
    return;
  }

  // route.matched[1] is the second matched route record for the current route
  navViewName.value = route.matched[1].name.toUpperCase();
  store.filesTag = "ALL";
  switch (navViewName.value) {
    case "FILES":
      valueToSet = activePage.value;
      break;
    case "DISCOVER":
      switch (name) {
        case "Map":
        case "CheckMap":
          valueToSet = "MAP";
          break;
        case "Conformance":
        case "CheckConformance":
          valueToSet = "CONFORMANCE";
          break;
        case "Performance":
        case "CheckPerformance":
          valueToSet = "PERFORMANCE";
          break;
      }
      break;
    case "COMPARE":
      switch (name) {
        case "MapCompare":
          valueToSet = "MAP";
          break;
        case "CompareDashboard":
          valueToSet = "PERFORMANCE";
          break;
        default:
          break;
      }
      break;
  }

  // Frontend is not sure which button will the user press on the modal,
  // so here we need to save to a pending state
  // The frontend cannot determine which modal button the user will press
  // (cancel or confirm/save), so we save it to a pending state.
  if (!shouldKeepPreviousPage.value) {
    // If the user did not press cancel
    setPendingActivePage(valueToSet);
  }

  return valueToSet;
}

/** Opens the save modal for Map or Conformance pages. */
async function saveModal() {
  // Help determine MAP/CONFORMANCE save with "submit" or "cancel".
  // Notify Map to close the Sidebar.
  emitter.emit("saveModal", false);

  switch (route.name) {
    case "Map":
      await handleMapSave();
      break;
    case "CheckMap":
      await handleCheckMapSave();
      break;
    case "Conformance":
    case "CheckConformance":
      await handleConformanceSave();
      break;
    default:
      break;
  }
}

/** Sets nav item button background color when the active page is empty. */
function handleNavItemBtn() {
  if (activePageComputedByRoute.value === "") {
    setActivePageComputedByRoute(route.matched[route.matched.length - 1].name);
  }
}

/** Saves or creates a filter for the Map page. */
async function handleMapSave() {
  if (createFilterId.value) {
    await allMapDataStore.updateFilter();
    if (isUpdateFilter.value) {
      await savedSuccessfully(filterName.value);
    }
  } else if (logId.value) {
    const isSaved = await saveFilter(allMapDataStore.addFilterId);
    if (isSaved) {
      setActivePage("MAP");
      await router.push(`/discover/filter/${createFilterId.value}/map`);
    }
  }
}

/** Saves a filter from the Check Map page. */
async function handleCheckMapSave() {
  const isSaved = await saveFilter(allMapDataStore.addFilterId);
  if (isSaved) {
    setActivePage("MAP");
    await router.push(`/discover/filter/${createFilterId.value}/map`);
  }
}

/** Saves or updates conformance check data. */
async function handleConformanceSave() {
  if (
    conformanceFilterCreateCheckId.value ||
    conformanceLogCreateCheckId.value
  ) {
    await conformanceStore.updateConformance();
    if (isUpdateConformance.value) {
      await savedSuccessfully(conformanceFileName.value);
    }
  } else {
    const isSaved = await saveConformance(
      conformanceStore.addConformanceCreateCheckId,
    );
    if (isSaved) {
      if (conformanceLogId.value) {
        setActivePage("CONFORMANCE");
        await router.push(
          `/discover/conformance/log/${conformanceLogCreateCheckId.value}/conformance`,
        );
      } else if (conformanceFilterId.value) {
        setActivePage("CONFORMANCE");
        await router.push(
          `/discover/conformance/filter/${conformanceFilterCreateCheckId.value}/conformance`,
        );
      }
    }
  }
}

onMounted(() => {
  handleNavItemBtn();
  if (route.params.type === "filter") {
    createFilterId.value = route.params.fileId;
  }
  showNavbarBreadcrumb.value = route.matched[0].name !== "AuthContainer";
  getNavViewName();
});
</script>
<style scoped>
#searchFiles::-webkit-search-cancel-button {
  appearance: none;
}
</style>
