<script setup lang="ts">
/* ================================
 * Imports
 * ================================ */
import { ref, computed, watch, onMounted, onBeforeUnmount, nextTick } 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 / Reactive base state
 * ================================ */
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); // Settings 버튼으로 온/오프
const lastNonAdminPath = ref<string>("/home");

/* ================================
 * Auth / Role helpers
 * ================================ */
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();
  let roles = auth?.userInfo?.roles ?? auth?.roles ?? [];
  if (typeof roles === "string") {
    roles = roles.split(",").map((s: string) => String(s).trim());
  }
  const rolesArr = Array.isArray(roles) ? roles : [];
  const roleStrings = rolesArr.map((r) =>
    typeof r === "object" && r !== null && "authority" in r
      ? String((r as { authority?: string }).authority ?? "")
      : typeof r === "object" && r !== null && "name" in r
        ? String((r as { name?: string }).name ?? "")
        : String(r),
  );
  const authCd = String(
    auth?.userInfo?.authCd ?? auth?.authCd ?? auth?.auth ?? "",
  ).toUpperCase();
  const username =
    auth?.userInfo?.username ?? auth?.username ?? auth?.userName ?? "";

  const inRoles = roleStrings.some(
    (r) => r === "ROLE_ADMIN" || String(r).toUpperCase() === "ADMIN",
  );
  isAdmin.value =
    inRoles ||
    authCd === "ADMIN" ||
    String(username).toLowerCase() === "admin";
}

function updateUsername() {
  const auth = readAuth();
  username.value = auth?.userInfo?.username ?? auth?.username ?? "";
}

/* ================================
 * Derived route state
 *  - /select 에서는 상단 메뉴 전체 숨김
 *  - 관리자 탭 표시 조건: adminMode ON || 관리자 라우트
 * ================================ */
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("/system-status") ||
    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);

/* ================================
 * Header dropdown menu
 * ================================ */
const menu = ref<MenuItem[]>([]);
const menuItemsBase: MenuItem[] = [
  { title: "Select Project", click: () => goSelect() },
  {
    title: "Change Password",
    click: () => {
      /* open modal */
    },
  },
  { title: "Logout", icon: "mdi-logout", click: () => logOut() },
];

/* ================================
 * Navigation actions
 * ================================ */
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");
  }
}

/** 관리자 메뉴 클릭 시 해당 경로로 이동 (SPA 실패 시 location으로 fallback) */
function goToAdminMenu(path: string | undefined) {
  if (!path) return;
  router.push(path).catch((err) => {
    if (err?.name !== "NavigationDuplicated") console.warn("admin nav", err);
  });
  setTimeout(() => {
    if (route.path !== path && path === "/system-status") {
      window.location.href = resolveHref(path);
    }
  }, 200);
}

/** base 포함 전체 href (클릭 시 네트워크 요청·이동 보장용) */
function resolveHref(path: string | undefined): string {
  if (!path) return "#";
  try {
    return router.resolve(path).href;
  } catch {
    return path.startsWith("/") ? path : "/" + path;
  }
}

/** 우측 드롭다운에서 관리자(경로) 항목인지 */
function isAdminMenuItem(item: MenuItem): boolean {
  return !!item.path && item.path.startsWith("/system-status");
}

/** 우측 드롭다운 메뉴 클릭: click 있으면 먼저 실행, 없으면 path로 이동 */
function onMenuItemClick(item: MenuItem, e?: MouseEvent) {
  e?.preventDefault();
  e?.stopPropagation();
  if (item.click) {
    item.click();
  } else if (item.path) {
    router.push(item.path);
  }
}

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();
    computeIsAdmin();
    if (!isAdminRoute.value) lastNonAdminPath.value = route.fullPath || "/home";
  },
  { immediate: true },
);

// storage 이벤트 동기화
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
 * ================================ */
const menuItems = computed<MenuItem[]>(() => {
  const items = [...menuItemsBase];
  if (isAdmin.value) {
    items.splice(1, 0, {
      title: "사용자 관리",
      icon: "mdi-account-multiple",
      path: "/users",
      click: () => router.push("/users"),
    });
    items.splice(2, 0, {
      title: "관리자",
      icon: "mdi-cog",
      path: "/system-status",
      click: () => goToAdminMenu("/system-status"),
    });
  }
  return items;
});

watch(menuItems, (v) => {
  menu.value = v;
}, { immediate: true });

onMounted(() => {
  updateUsername();
  computeIsAdmin();
  refreshProjectName();
  menu.value = menuItems.value;
  window.addEventListener("storage", onStorage);
});

onBeforeUnmount(() => {
  window.removeEventListener("storage", onStorage);
});
</script>

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

      <!-- 중앙: 메뉴 그룹 (Settings 전/후 분기) -->
      <div class="center-nav d-none d-md-flex" v-if="!hideAllMenus">
        <template v-if="showAdminTabs">
          <template v-for="(m, i) in adminMenus" :key="'am_' + i">
            <!-- 드롭다운 있는 항목 -->
            <v-menu
              v-if="m.depth?.length"
              open-on-hover
              close-on-content-click
              location="bottom"
            >
              <template #activator="{ props }">
                <v-btn
                  v-bind="props"
                  variant="text"
                  class="nav-btn"
                  :class="{
                    'nav-active': m.depth?.some((d: any) =>
                      isLinkActive(d.path),
                    ),
                  }"
                  append-icon="mdi-chevron-down"
                >
                  <v-icon start :icon="m.icon" class="mr-1" />
                  {{ m.title }}
                </v-btn>
              </template>

              <v-list density="compact" class="min-w-48">
                <v-list-item
                  v-for="(d, j) in m.depth"
                  :key="'amd_' + j"
                  :title="d.title"
                  :to="d.path"
                  :active="isLinkActive(d.path)"
                  active-class="nav-active"
                />
              </v-list>
            </v-menu>

            <!-- 드롭다운 없는 단일 항목: 버튼/링크 둘 다 클릭 시 이동 (Project/Users에서도 동작) -->
            <a
              v-else
              :href="resolveHref(m.path)"
              class="admin-nav-link"
              @click.prevent="goToAdminMenu(m.path)"
            >
              <v-btn
                variant="text"
                class="nav-btn"
                :class="{ 'nav-active': isLinkActive(m.path) }"
                @click.prevent="goToAdminMenu(m.path)"
              >
                <v-icon start :icon="m.icon" class="mr-1" />
                {{ m.title }}
              </v-btn>
            </a>
          </template>
        </template>

        <!-- 기본 메뉴 -->
        <template v-else>
          <template v-for="(m, i) in baseMenus" :key="'m_' + i">
            <v-menu
              v-if="m.depth?.length"
              open-on-hover
              close-on-content-click
              location="bottom"
              transition="scale-transition"
            >
              <template #activator="{ props }">
                <v-btn
                  v-bind="props"
                  variant="text"
                  class="nav-btn text-white"
                  :class="{
                    'nav-active': m.depth?.some((d: any) =>
                      isLinkActive(d.path),
                    ),
                  }"
                  append-icon="mdi-chevron-down"
                >
                  <v-icon start :icon="m.icon" class="mr-1" />
                  {{ m.title }}
                </v-btn>
              </template>

              <!-- ✅ 여기부터: Run 전용 디자인 -->
              <template
                v-if="
                  (m.title && m.title.toLowerCase() === 'run') ||
                  (m.path && m.path.startsWith('/run'))
                "
              >
                <v-card rounded="lg" elevation="12" class="px-2 py-2">
                  <v-list density="comfortable" lines="one" class="min-w-48">
                    <template v-for="(d, j) in m.depth" :key="'run_' + j">
                      <v-hover v-slot="{ isHovering, props: liProps }">
                        <v-list-item
                          v-bind="liProps"
                          :title="d.title"
                          :to="d.path"
                          :active="isLinkActive(d.path)"
                          :rounded="'lg'"
                          :variant="
                            isHovering || isLinkActive(d.path)
                              ? 'tonal'
                              : 'text'
                          "
                          class="mx-2 my-1"
                        />
                      </v-hover>
                    </template>
                  </v-list>
                </v-card>
              </template>

              <template v-else>
                <v-list density="compact" class="min-w-48 subnav-list">
                  <v-list-item
                    v-for="(d, j) in m.depth"
                    :key="'d_' + j"
                    :title="d.title"
                    :to="d.path"
                    class="submenu-item"
                    :class="{ 'submenu-active': isLinkActive(d.path) }"
                  />
                </v-list>
              </template>
            </v-menu>

            <v-btn
              v-else
              variant="text"
              class="nav-btn"
              :class="{ 'nav-active': isLinkActive(m.path) }"
              @click="m.path && router.push(m.path)"
            >
              <v-icon start :icon="m.icon" class="mr-1" />
              {{ m.title }}
            </v-btn>
          </template>
        </template>
      </div>

      <v-spacer />

      <!-- 우측: 기존 기능 유지 -->
      <v-tooltip v-if="isAdmin" location="bottom" text="Settings">
        <template #activator="{ props }" v-if="!hideAllMenus">
          <v-btn
            icon
            class="mr-2 text-white"
            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
            class="mr-2 text-white"
            @click="goSelect"
            v-bind="props"
            aria-label="Project"
          >
            <v-icon>mdi-file-tree</v-icon>
          </v-btn>
        </template>
      </v-tooltip>

      <!-- 사용자 관리 (관리자만, Project 버튼 옆) -->
      <v-tooltip v-if="isAdmin && !hideAllMenus" location="bottom" text="사용자 관리">
        <template #activator="{ props }">
          <v-btn
            icon
            class="mr-2 text-white flex-shrink-0"
            v-bind="props"
            @click="router.push('/users')"
            aria-label="사용자 관리"
          >
            <v-icon>mdi-account-multiple</v-icon>
          </v-btn>
        </template>
      </v-tooltip>

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

      <v-menu location="bottom end">
        <template #activator="{ props }">
          <v-btn icon v-bind="props" class="mr-1 text-white">
            <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"
            :to="item.path && !isAdminMenuItem(item) ? item.path : undefined"
            :prepend-icon="item.icon"
            :href="isAdminMenuItem(item) ? resolveHref(item.path) : undefined"
            @click.stop.prevent="onMenuItemClick(item, $event)"
          >
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </v-app-bar>

    <!-- 본문 -->
    <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: #121212 !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;
  color: #fff;
  cursor: pointer;
}

/* 중앙 고정 네비게이션 */
.center-nav {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  gap: 8px;
  align-items: center;
}

/* 관리자 메뉴 router-link: 링크 스타일 제거 */
.admin-nav-link {
  text-decoration: none;
  color: inherit;
  display: inline-flex;
}

.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;
}

/* 드롭다운(하위 메뉴)도 동일 룩으로 */
.subnav-list {
  background: transparent; /* 탑바 느낌 유지 */
}

.submenu-item {
  color: #fff !important;
  border-radius: 10px;
  margin: 2px 8px;
}

.submenu-item:hover {
  background: rgba(59, 130, 246, 0.08);
}

.submenu-active {
  background: rgba(59, 130, 246, 0.22);
  color: #fff !important;
}
.min-w-48 {
  min-width: 12rem;
}

.userbox {
  min-width: 180px;
}
</style>
