<script setup lang="ts">
/* ================================
 * Imports
 * ================================ */
import { ref, computed, watch, onMounted, onBeforeUnmount } from "vue";
import { useRoute, useRouter } from "vue-router";
import { storage } from "@/utils/storage.js";
import { UserManagerService } from "@/components/service/management/userManagerService";
import { menuUtils } from "@/utils/menuUtils";

/* ================================
 * Types
 * ================================ */
type MenuItem = {
  title: string;
  icon?: string;
  path?: string;
  depth?: Array<{ title: string; path: string }>;
  click?: () => void;
};

/* ================================
 * Router / Base states
 * ================================ */
const route = useRoute();
const router = useRouter();

const username = ref<string>("");
const projectName = ref<string>(localStorage.getItem("projectName") || "");

const isAdmin = ref<boolean>(false);
const adminMode = ref<boolean>(false);
const lastNonAdminPath = ref<string>("/home");

function readAuth() {
  try {
    const raw =
      typeof storage?.getAuth === "function"
        ? storage.getAuth()
        : JSON.parse(localStorage.getItem("autoflow-auth") || "null");
    return raw ?? null;
  } catch {
    return null;
  }
}
function computeIsAdmin() {
  const auth = readAuth();
  const roles = auth?.userInfo?.roles ?? auth?.roles ?? [];
  const authCd = auth?.userInfo?.authCd ?? auth?.authCd ?? auth?.auth;
  const inRoles = Array.isArray(roles)
    ? roles.includes("ROLE_ADMIN")
    : roles === "ROLE_ADMIN";
  isAdmin.value = inRoles || authCd === "ADMIN";
}
function updateUsername() {
  const auth = readAuth();
  username.value = auth?.userInfo?.username ?? auth?.username ?? "";
}

/* ================================
 * Derived route state
 * ================================ */
const hideAllMenus = computed<boolean>(() => route.path.startsWith("/select"));

const isAdminRoute = computed<boolean>(() => {
  const p = route.path || "";
  const hitPath =
    p.startsWith("/project") ||
    p.startsWith("/users") ||
    p.startsWith("/select");
  const hitMeta = route.matched.some((r) => r.meta?.requiresAdmin);
  return hitPath || hitMeta;
});
const showAdminTabs = computed<boolean>(
  () => adminMode.value || isAdminRoute.value,
);

/* ================================
 * Menus
 * ================================ */
const baseMenus = computed<MenuItem[]>(
  () => (menuUtils?.menuItem ?? []) as MenuItem[],
);
const adminMenus = computed<MenuItem[]>(() => {
  const fromUtil = (menuUtils?.adminMenuItem ?? []) as MenuItem[];
  return fromUtil.length
    ? fromUtil
    : [
        { title: "Projects", icon: "mdi-briefcase", path: "/project" },
        { title: "Users", icon: "mdi-account-multiple", path: "/users" },
      ];
});
const isLinkActive = (path?: string) => !!path && route.path.startsWith(path);

/* ================================
 * 사용자 메뉴 (우측)
 * ================================ */
const menu = ref<MenuItem[]>([]);
const menuItems: MenuItem[] = [
  { title: "Select Project", click: () => goSelect() },
  { title: "Change Password", click: () => {} },
  { title: "Logout", icon: "mdi-logout", click: () => logOut() },
];

/* ================================
 * 상단 Hover 하위 메뉴 스트립
 * ================================ */
type DepthItem = { title: string; path: string };

const hoverBar = ref<{
  open: boolean;
  items: DepthItem[];
}>({ open: false, items: [] });

let hideTimer: number | null = null;

function showHoverStrip(m: MenuItem) {
  if (!m.depth?.length) return;
  if (hideTimer) {
    window.clearTimeout(hideTimer);
    hideTimer = null;
  }
  hoverBar.value = {
    open: true,
    items: m.depth,
  };
}
function scheduleHideStrip() {
  if (hideTimer) window.clearTimeout(hideTimer);
  hideTimer = window.setTimeout(() => {
    hoverBar.value.open = false;
  }, 140);
}
function keepStrip() {
  if (hideTimer) {
    window.clearTimeout(hideTimer);
    hideTimer = null;
  }
}

/* ================================
 * Navigation
 * ================================ */
function goMain() {
  adminMode.value = false;
  router.push("/home");
}
function goSelect() {
  adminMode.value = false;
  router.push("/select");
}
function toggleAdmin() {
  if (!isAdmin.value) return;
  if (adminMode.value) {
    adminMode.value = false;
    router.push("/home");
  } else {
    adminMode.value = true;
    if (!isAdminRoute.value) router.push("/project");
  }
}
function logOut() {
  UserManagerService.signOut()
    .catch(console.error)
    .finally(() => {
      localStorage.removeItem("autoflow-auth");
      localStorage.removeItem("external-auth");
      localStorage.removeItem("projectName");
      localStorage.removeItem("projectId");
      sessionStorage.removeItem("initialRedirectDone");
      username.value = "";
      projectName.value = "";
      adminMode.value = false;
      router.push("/login");
    });
}

/* ================================
 * Effects
 * ================================ */
function refreshProjectName() {
  projectName.value = localStorage.getItem("projectName") || "";
}
watch(
  () => route.fullPath,
  () => {
    refreshProjectName();
    // 라우트가 바뀌면 스트립 닫기
    hoverBar.value.open = false;
    if (!isAdminRoute.value) lastNonAdminPath.value = route.fullPath || "/home";
  },
  { immediate: true },
);
function onStorage(e: StorageEvent) {
  if (!e.key || e.key === "projectName") {
    refreshProjectName();
    adminMode.value = false;
  }
  if (!e.key || e.key === "autoflow-auth" || e.key === "auth") {
    updateUsername();
    computeIsAdmin();
  }
}

/* ================================
 * Lifecycle
 * ================================ */
onMounted(() => {
  updateUsername();
  computeIsAdmin();
  refreshProjectName();
  menu.value = menuItems;
  window.addEventListener("storage", onStorage);
});
onBeforeUnmount(() => {
  window.removeEventListener("storage", onStorage);
  if (hideTimer) window.clearTimeout(hideTimer);
});
</script>

<template>
  <v-app>
    <!-- ===== 상단 탑바 ===== -->
    <v-app-bar flat height="64" class="topbar">
      <div
        variant="text"
        size="large"
        class="brand-btn text-h5 text-primary"
        @click="goMain"
        aria-label="Home"
      >
        AUTOFLOW WEB CONSOLE
      </div>

      <!-- ✅ 여기 스페이서를 '브랜드 다음'에 둬서 오른쪽으로 밀기 -->
      <v-spacer />

      <!-- ✅ 메뉴는 우측 정렬 -->
      <div class="right-nav d-none d-md-flex" v-if="!hideAllMenus">
        <!-- 관리자 메뉴 -->
        <template v-if="showAdminTabs">
          <template v-for="(m, i) in adminMenus" :key="'am_' + i">
            <v-btn
              variant="text"
              class="nav-btn"
              :class="{
                'nav-active':
                  m.depth?.some((d: any) => isLinkActive(d.path)) ||
                  isLinkActive(m.path),
              }"
              @mouseenter="showHoverStrip(m)"
              @mouseleave="scheduleHideStrip"
              @click="m.path && router.push(m.path)"
            >
              <v-icon start :icon="m.icon" class="mr-1" />
              {{ m.title }}
            </v-btn>
          </template>
        </template>

        <!-- 기본 메뉴 -->
        <template v-else>
          <template v-for="(m, i) in baseMenus" :key="'m_' + i">
            <v-btn
              variant="text"
              class="nav-btn text-white"
              :class="{
                'nav-active':
                  m.depth?.some((d: any) => isLinkActive(d.path)) ||
                  isLinkActive(m.path),
              }"
              @mouseenter="showHoverStrip(m)"
              @mouseleave="scheduleHideStrip"
              @click="!m.depth?.length && m.path && router.push(m.path)"
            >
              <v-icon start :icon="m.icon" class="mr-1" />
              {{ m.title }}
            </v-btn>
          </template>
        </template>
      </div>
      <!-- 우측 아이콘들 -->
      <v-tooltip v-if="isAdmin" location="bottom" text="Settings">
        <template #activator="{ props }" v-if="!hideAllMenus">
          <v-btn
            icon
            color="primary"
            class="mr-2"
            v-bind="props"
            @click="toggleAdmin"
            aria-label="Settings"
          >
            <v-icon>mdi-cog</v-icon>
          </v-btn>
        </template>
      </v-tooltip>

      <v-tooltip location="bottom" text="Project">
        <template #activator="{ props }">
          <v-btn
            icon
            color="primary"
            class="mr-2"
            @click="goSelect"
            v-bind="props"
            aria-label="Project"
          >
            <v-icon>mdi-file-tree</v-icon>
          </v-btn>
        </template>
      </v-tooltip>

      <div class="d-none d-md-flex flex-column align-end userbox">
        <div class="font-weight-black">{{ username || "GUEST" }}</div>
        <div class="text-subtitle-2">
          {{ projectName || "No Project Selected" }}
        </div>
      </div>

      <v-menu location="bottom end">
        <template #activator="{ props }">
          <v-btn icon color="primary" v-bind="props" class="mr-1">
            <v-icon>mdi-arrow-down-drop-circle-outline</v-icon>
          </v-btn>
        </template>
        <v-list>
          <v-list-item
            v-for="(item, index) in menu"
            :key="index"
            :value="index"
            @click="item.click"
            :prepend-icon="item.icon"
          >
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </v-app-bar>

    <!-- ===== 상단 하위 메뉴 스트립 (호버 시 표시) ===== -->
    <v-slide-y-transition>
      <v-sheet
        v-if="hoverBar.open"
        class="hover-strip"
        elevation="8"
        color="surface"
        @mouseenter="keepStrip"
        @mouseleave="scheduleHideStrip"
      >
        <v-container class="py-2" :fluid="true">
          <!-- 중앙 정렬 -->
          <v-row class="g-2" no-gutters justify="center" align="center">
            <v-col class="d-flex flex-wrap justify-center" cols="12">
              <v-btn
                v-for="d in hoverBar.items"
                :key="d.path"
                size="small"
                class="mx-1 my-1 strip-chip"
                :variant="isLinkActive(d.path) ? 'tonal' : 'text'"
                :color="isLinkActive(d.path) ? 'primary' : undefined"
                @click="router.push(d.path)"
              >
                {{ d.title }}
              </v-btn>
            </v-col>
          </v-row>
        </v-container>
      </v-sheet>
    </v-slide-y-transition>

    <!-- 본문 -->
    <v-main>
      <v-container
        fluid
        class="pa-16 background d-flex justify-center"
        style="width: 100%"
      >
        <slot />
      </v-container>
    </v-main>
  </v-app>
</template>

<style scoped>
.topbar {
  background: rgba(18, 18, 18, 0.7) !important;
  backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

/* 브랜드 */
.brand-btn {
  font-weight: 800;
  letter-spacing: 0.08em;
  padding: 0 14px;
}

.right-nav {
  display: flex;
  align-items: center;
  gap: 8px; /* 버튼 간격 */
  justify-content: flex-end;
}
.nav-btn {
  text-transform: none;
  border-radius: 10px;
  padding: 0 16px;
  font-size: 14px;
  color: #fff !important;
}
.nav-btn:hover {
  background: rgba(59, 130, 246, 0.08);
}
.nav-active {
  background: rgba(59, 130, 246, 0.22);
  height: 46px;
  color: #fff !important;
}

.userbox {
  min-width: 180px;
}

/* ===== 호버 스트립 (상단 바로 아래, 이미지 스타일) ===== */
.hover-strip {
  position: fixed;
  top: var(--v-layout-top, 64px); /* app-bar 바로 아래 */
  left: 0;
  right: 0;
  z-index: 2500;
  /* 다크 배경 + 살짝 투명 + 경계 */
  background: rgba(32, 32, 32, 0.96);
  border-bottom: 1px solid rgb(145, 61, 61);
  backdrop-filter: blur(6px);
}

/* 버튼(알약) – 다크에서도 비활성 글자/테두리 선명 */
.strip-chip {
  border-radius: 9999px !important;
  text-transform: none;
  font-weight: 600;
  letter-spacing: 0;
  height: 30px;
  padding: 0 14px;
  color: #e5e7eb !important; /* 비활성도 흐려 보이지 않게 */
}

.strip-chip.v-btn--variant-text {
  /* text 변형일 때도 흐릿하지 않게 약한 테두리 */
  border: 1px solid rgba(255, 255, 255, 0.14) !important;
  background: transparent !important;
}

.strip-chip:hover {
  background: rgba(255, 255, 255, 0.06) !important;
}
</style>
