<script setup lang="ts">
import { useGameDataStore } from '#layers/stores/useGameDataStore'
import { useScrollStore } from '#layers/stores/useScrollStore'
import { onClickOutside, useWindowSize } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import type {
  GameDataValue,
  GameDataMenu,
  GameDataMenuChildren,
} from '#layers/types/api/gameData'

const route = useRoute()
const { width } = useWindowSize()
const gameDataStore = useGameDataStore()
const scrollStore = useScrollStore()

const { isPassedStoveGnb, scrollGnbPosition } = storeToRefs(scrollStore)

const navAreaRef = ref<HTMLElement>()
const startRef = ref<HTMLElement>()

const gameData = gameDataStore.gameData as GameDataValue
const gnbData = gameData?.gnb
const isMenuOpen = ref(false)
const navWidth = ref(0)
const startWidth = ref(0)
const officialItemWidths = ref<number[]>([])
const overflowNam = ref<number>(0)

const currentPath = computed(() => formatPathWithoutLocale(route.path))

const pathMatches = (base: string, current: string) => {
  if (!base || base === '/') return current === '/'
  return current === base || current.startsWith(base + '/')
}

/** 자식 중 활성 링크 존재 여부 */
const hasActiveChild = (children?: GameDataMenuChildren) => {
  const cur = currentPath.value
  return formatToArray(children).some(child => {
    if (!child?.url_path || !isInternalUrl(child.url_path)) return false
    return pathMatches(formatPathWithoutLocale(child.url_path), cur)
  })
}

/** 1Depth 활성화 여부 */
const isNavItemActive = (gnbItem: GameDataMenu): boolean => {
  const cur = currentPath.value
  const base = gnbItem?.url_path
  const selfActive =
    !!base &&
    isInternalUrl(base) &&
    pathMatches(formatPathWithoutLocale(base), cur)
  return selfActive || hasActiveChild(gnbItem.children)
}

const handleMenuOpen = () => (isMenuOpen.value = true)
const handleMenuClose = () => (isMenuOpen.value = false)

// navAreaRef의 넓이를 구하는 함수
const calculateNavWidth = () => {
  if (!navAreaRef.value || !gnbData) return 0

  const navAreaWidth = navAreaRef.value.offsetWidth
  const moreWidth = 72 // 더보기 버튼 넓이 + 마진
  return navAreaWidth + moreWidth
}

// startRef의 넓이를 구하는 함수
const calculateStartWidth = () => {
  if (!startRef.value || !gnbData) return 0

  const startWidth = startRef.value.offsetWidth
  const headerRightPadding = 40 // 헤더 오른쪽 마진
  return startWidth + headerRightPadding
}

// official 자식들의 넓이를 구하는 함수
const calculateOfficialItemWidths = () => {
  if (!navAreaRef.value) return

  const officialItems = navAreaRef.value.querySelectorAll('.official .nav-item')
  const widths: number[] = []

  // 뒤에서부터 순서대로 넓이 계산
  for (let i = officialItems.length - 1; i >= 0; i--) {
    const item = officialItems[i] as HTMLElement
    if (item) {
      widths.push(item.offsetWidth)
    }
  }

  officialItemWidths.value = widths

  // 해상도 체크 및 오버플로우 계산
  calculateOverflow()
}

// 오버플로우 계산 함수
const calculateOverflow = () => {
  if (!navAreaRef.value || !startRef.value) return

  const totalNavWidth = navWidth.value + startWidth.value
  const screenWidth = width.value

  // 모바일(1024px 미만)에서는 overflowNam을 0으로 설정
  if (screenWidth < 1024) {
    overflowNam.value = 0
    return
  }

  // 해상도가 navWidth + startWidth보다 작은 경우
  if (screenWidth < totalNavWidth) {
    let removedCount = 0
    let currentTotal = totalNavWidth

    for (let i = 0; i < officialItemWidths.value.length; i++) {
      currentTotal -= officialItemWidths.value[i]
      removedCount++

      if (currentTotal <= screenWidth) {
        break
      }
    }

    overflowNam.value = removedCount
  } else {
    overflowNam.value = 0
  }
}

const stopClickOutside = onClickOutside(
  navAreaRef,
  () => (isMenuOpen.value = false)
)

// 화면 크기 변경 시 오버플로우 재계산
watch(width, () => {
  calculateOverflow()
})

onMounted(() => {
  overflowNam.value = 0

  nextTick(() => {
    if (navAreaRef.value && startRef.value) {
      navWidth.value = calculateNavWidth()
      startWidth.value = calculateStartWidth()
      calculateOfficialItemWidths()
    }
  })
})

onBeforeUnmount(() => {
  if (stopClickOutside) {
    stopClickOutside()
  }
})
</script>

<template>
  <header class="header">
    <BlocksStoveGnb class="min-h-[48px]" />

    <div class="game-wrapper" :class="{ 'is-fixed': isPassedStoveGnb }">
      <AtomsLocaleLink to="/brand" class="mx-auto md:hidden">
        <img
          :src="gnbData?.bi_path"
          :alt="gameData?.game_name"
          class="h-[30px]"
        />
      </AtomsLocaleLink>
      <button class="btn-open" @click="handleMenuOpen">
        <AtomsIconsMenuBoldLine class="mx-auto" />
        <span class="sr-only">menu open</span>
      </button>
      <div
        :class="['gnb-game', { 'is-open': isMenuOpen }]"
        :style="{ '--scroll-position': scrollGnbPosition + 'px' }"
      >
        <div ref="navAreaRef" class="nav-area">
          <div class="nav-logo">
            <AtomsLocaleLink to="/brand" @click="handleMenuClose">
              <img
                :src="gnbData?.bi_path"
                :alt="gameData?.game_name"
                class="h-[30px]"
              />
            </AtomsLocaleLink>
          </div>
          <nav class="nav-list">
            <div v-if="gnbData?.menus" class="official">
              <div
                v-for="(gnbItem, key) in gnbData?.menus"
                :key="key"
                class="nav-item"
                :class="{
                  'is-hidden':
                    overflowNam > 0 &&
                    Number(key) >=
                      Object.keys(gnbData?.menus).length - overflowNam,
                }"
              >
                <BlocksHybridLink
                  :to="gnbItem.url_path"
                  :target="gnbItem.link_target"
                  :class="['nav-1depth', { active: isNavItemActive(gnbItem) }]"
                >
                  <span>{{ gnbItem.menu_name }}</span>
                  <AtomsIconsArrowDownFill
                    v-if="gnbItem.children"
                    class="hidden md:block"
                  />
                </BlocksHybridLink>
                <Transition name="fade">
                  <div v-if="gnbItem.children" class="nav-2depth">
                    <ul>
                      <li
                        v-for="child in gnbItem.children"
                        :key="child.menu_name"
                      >
                        <BlocksHybridLink
                          :to="child.url_path"
                          :target="child.link_target"
                        >
                          <span>{{ child.menu_name }}</span>
                          <AtomsIconsWebLinkLine
                            v-if="child.link_target === '_blank'"
                          />
                        </BlocksHybridLink>
                      </li>
                    </ul>
                  </div>
                </Transition>
              </div>
            </div>
            <div v-if="gnbData?.menus && overflowNam > 0" class="more">
              <button class="btn-more">
                <AtomsIconsOptionHorizontalFill class="mx-auto" />
                <span class="sr-only">more</span>
              </button>
              <div class="more-list">
                <div class="list-inner">
                  <div
                    v-for="(gnbItem, key) in gnbData?.menus"
                    :key="key"
                    :class="{
                      hidden:
                        Number(key) <
                        Object.keys(gnbData?.menus).length - overflowNam,
                    }"
                  >
                    <BlocksHybridLink
                      :to="gnbItem.url_path"
                      :target="gnbItem.link_target"
                      :class="`${isNavItemActive(gnbItem) ? 'active' : ''}`"
                    >
                      <span>{{ gnbItem.menu_name }}</span>
                    </BlocksHybridLink>
                    <div v-if="gnbItem.children">
                      <ul>
                        <li
                          v-for="child in gnbItem.children"
                          :key="child.menu_name"
                        >
                          <BlocksHybridLink
                            :to="child.url_path"
                            :target="child.link_target"
                          >
                            <span>{{ child.menu_name }}</span>
                            <AtomsIconsWebLinkLine
                              v-if="child.link_target === '_blank'"
                            />
                          </BlocksHybridLink>
                        </li>
                      </ul>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div class="event">
              <div class="nav-item">
                <BlocksHybridLink
                  :to="'/event'"
                  :target="'_self'"
                  class="nav-1depth text-gradient-pink"
                >
                  <AtomsIconsStarFill />
                  <span>이벤트</span>
                  <AtomsIconsStarFill />
                </BlocksHybridLink>
              </div>
            </div>
          </nav>
          <div ref="startRef" class="btn-start">
            <BlocksButtonLuncher class="w-full md:w-auto">
              게임 시작
            </BlocksButtonLuncher>
          </div>
          <button class="btn-close" @click="handleMenuClose">
            <AtomsIconsMenuCloseLine class="mx-auto" />
            <span class="sr-only">menu close</span>
          </button>
        </div>
      </div>
    </div>
  </header>
</template>

<style scoped>
.header {
  @apply bg-theme-foreground text-theme-foreground-reversal relative z-50;
}
.game-wrapper {
  @apply absolute flex w-full h-[48px] items-center whitespace-nowrap px-[52px] bg-theme-foreground sm:px-[72px] md:h-16 md:pl-0 md:pr-[40px]
  before:content-[''] before:absolute before:top-0 before:left-0 before:right-0 before:h-px before:bg-theme-foreground-reversal-6;
}
.game-wrapper.is-fixed {
  @apply fixed top-0 left-0;
}
.game-logo {
  @apply mx-auto shrink-0 md:mx-0;
}

.btn-open,
.btn-close {
  @apply absolute w-[40px] h-[40px] md:hidden;
}
.btn-open {
  @apply top-[4px] left-[12px] sm:left-[32px];
}
.btn-close {
  @apply top-[11px] left-[12px];
}
.btn-start {
  @apply relative mt-2 px-5 md:absolute md:right-0 md:mt-0 md:px-0;
}

.gnb-game {
  @apply absolute top-0 left-0 w-0 md:relative md:w-full md:!h-full;
  height: calc(100vh - var(--scroll-position));
}
.gnb-game.is-open {
  @apply w-full;
}
.gnb-game.is-open::before {
  @apply content-[''] absolute inset-0 w-[100vw] h-full bg-[rgba(0,0,0,0.6)] md:hidden;
}
.gnb-game.is-open .nav-area {
  @apply h-full translate-x-0 transition-transform duration-300 md:transform-none;
}

.nav-area {
  @apply flex flex-col w-[100vw] max-w-[360px] min-w-[320px] bg-theme-foreground-10 translate-x-[-100%]
  md:inline-flex md:flex-row md:w-auto md:max-w-none md:h-full md:pl-[40px] md:items-center md:bg-transparent md:transform-none;
}

.nav-logo {
  @apply flex items-center justify-center shrink-0 h-[62px];
}

.nav-list {
  @apply overflow-hidden flex flex-col order-1 h-full mt-2 mb-4 px-2
  md:flex-row md:order-none md:h-full md:my-0 md:ml-10 md:mr-6 md:px-0 md:overflow-visible;
}

.nav-item {
  @apply relative flex flex-col text-[16px] md:items-center md:h-full;
}
.nav-item:last-of-type::after {
  @apply hidden;
}
.nav-item::after {
  @apply content-[''] h-px my-2 mx-3 bg-theme-foreground-reversal-8 md:hidden;
}
.nav-item:hover .nav-1depth::after,
.nav-1depth.active::after {
  @apply opacity-100 md:transition-opacity;
}
.nav-item:hover .nav-2depth {
  @apply md:block;
}

.nav-1depth {
  @apply flex items-center py-[9px] px-3 gap-1 rounded-[12px] md:h-full md:py-0 md:px-0;
}
.nav-1depth::after {
  @apply md:content-[''] md:absolute md:bottom-0 md:left-0 md:w-full md:h-[2px] md:bg-theme-foreground-reversal md:opacity-0;
}
.nav-1depth.active {
  @apply bg-theme-foreground-reversal-8 md:bg-transparent;
}

.nav-2depth {
  @apply text-[15px] md:hidden md:absolute md:top-[64px] md:left-[-28px] md:pt-1;
}
.nav-2depth ul {
  @apply bg-theme-foreground-10 rounded-[20px] md:min-w-[190px] md:p-3 md:shadow-lg;
}
.nav-2depth a {
  @apply flex items-center gap-1 py-[9px] px-5 rounded-[12px] transition-colors
  md:py-[11px] md:px-4
  hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10;
}

.official {
  @apply overflow-x-hidden overflow-y-auto pb-2 md:flex md:items-center md:space-x-8 md:pb-0 md:overflow-visible;
}

.more {
  @apply relative hidden ml-[32px] pt-[11px] md:block;
}
.more:hover .more-list {
  @apply md:block;
}
.btn-more {
  @apply w-[40px] h-[40px] rounded-[12px] bg-theme-foreground-reversal-6 hover:bg-theme-foreground-reversal-10 active:bg-theme-foreground-reversal-4;
}
.more-list {
  @apply hidden absolute top-[64px] left-[-20px] pt-1;
}
.list-inner {
  @apply min-w-[190px] p-3 rounded-[20px] bg-theme-foreground-10 shadow-lg;
}
.more-list a {
  @apply flex items-center gap-1 py-[10px] px-4 rounded-[12px] transition-colors
  hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10;
}
.more-list li a {
  @apply px-6;
}

.event {
  @apply relative md:ml-[64px] md:after:content-[''] md:after:absolute md:after:top-[50%] md:after:left-[-32px] md:after:w-[1px] md:after:h-[16px] md:after:bg-theme-foreground-gray-750 md:after:translate-y-[-50%];
}

.is-hidden {
  @apply hidden;
}
</style>
