<script setup lang="ts">
import { useThrottleFn } from '@vueuse/core'
import { useGameDataStore } from '#layers/stores/useGameDataStore'
import type {
  GameDataMenu,
  GameDataMenuChildren,
  GameDataResourceGroup,
  GameDataResourceGroupSet,
} from '#layers/types/api/gameData'
import type { TrackingObject } from '#layers/types/api/common'

const MORE_WIDTH = 72
const START_MARGIN = 40

const route = useRoute()
const { locale, tm } = useI18n()
const { width } = useWindowSize()
const gameDataStore = useGameDataStore()
const pageDataStore = usePageDataStore()
const scrollStore = useScrollStore()
const breakpoints = useResponsiveBreakpoints()
const { sendLog } = useAnalytics()

const { gameId, gameName, imgJson, gnb, eventBanner } =
  storeToRefs(gameDataStore)
const { pageLayoutType } = storeToRefs(pageDataStore)
const { isPassedStoveGnb } = storeToRefs(scrollStore)

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

const { width: startWidth } = useElementSize(startRef)

const isMounted = ref(false)
const isMenuOpen = ref(false)
const navWidth = ref(0)
const officialItemWidths = ref<number[]>([])
const overflowCount = ref<number>(0)

const biSmallPath = computed(() => imgJson.value?.bi_small)
const gnbMenusCount = computed(() => {
  const menus = gnb.value?.menus
  if (!menus || typeof menus !== 'object') return 0
  return Object.keys(menus).length
})
const currentPath = computed(() => formatPathWithoutLocale(route.path))
const start1depthData = computed(
  () => gnb.value?.buttons[0]?.button_json as GameDataResourceGroup
)
const start2depthData = computed(
  () => gnb.value?.buttons[1]?.button_json as GameDataResourceGroupSet
)

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

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

  const navAreaWidth = navAreaRef.value.offsetWidth
  navWidth.value = navAreaWidth + MORE_WIDTH
}

// official 자식들의 넓이를 구하는 함수
const calculateOfficialItemWidths = () => {
  if (!import.meta.client) return
  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
}

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

  if (breakpoints.value.isMobile) {
    overflowCount.value = 0
    return
  }

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

  // 해상도가 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
      }
    }

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

// 100ms마다 최대 1회 실행
const throttledCalculateOverflow = useThrottleFn(calculateOverflow, 100)

const isNotClickable = (gnbItem: GameDataMenu) => {
  return gnbItem.click_action_type === 0
}

const has2depthButton = (gnbItem: GameDataMenu) => {
  return gnbItem.children && Object.keys(gnbItem.children).length > 0
}

const handleMenuOpen = () => {
  isMenuOpen.value = true
  scrollStore.controlScrollLock(true)
}

const handleMenuClose = () => {
  isMenuOpen.value = false
  scrollStore.controlScrollLock(false)
}

const handleSendLog = (item: string | TrackingObject) => {
  const analytics: TrackingObject =
    typeof item === 'string'
      ? {
          action_type: 'click',
          click_item: item,
          click_sarea: 'GNB',
          click_area: gameId.value,
        }
      : { ...item, click_area: gameId.value }
  sendLog(locale.value, analytics)
}

const handleGnbItemClick = (gnbItem: GameDataMenu) => {
  if (isNotClickable(gnbItem)) return

  handleMenuClose()
  handleSendLog(gnbItem.tracking_json)
}

onMounted(() => {
  overflowCount.value = 0
  isMounted.value = true

  // 초기 계산
  nextTick(() => {
    calculateNavWidth()
    calculateOfficialItemWidths()
    calculateOverflow()
  })

  watchEffect(() => {
    if (!startWidth.value) return
    throttledCalculateOverflow()
  })

  // 화면 크기 변경 시 오버플로우 재계산
  watch(width, () => {
    throttledCalculateOverflow()
    if (isMenuOpen.value && breakpoints.value.isDesktop) {
      handleMenuClose()
    }
  })
})
</script>

<template>
  <header :class="['header', { 'empty-game': !gnb }]">
    <BlocksStoveGnb class="h-[48px]" />
    <div v-if="gnb" :class="['game-wrap', { 'is-fixed': isPassedStoveGnb }]">
      <AtomsLocaleLink
        to="/home"
        class="mx-auto md:hidden"
        @click="handleSendLog('BI')"
      >
        <img
          :src="formatPathHost(biSmallPath)"
          :alt="gameName"
          class="h-[30px]"
        />
      </AtomsLocaleLink>
      <button class="btn-open" @click="handleMenuOpen">
        <AtomsIconsMenuBoldLine class="mx-auto" />
        <span class="sr-only">menu open</span>
      </button>
      <div
        :class="['nav-wrap', { 'is-open': isMenuOpen }]"
        @click="handleMenuClose"
      >
        <div ref="navAreaRef" class="nav-area" @click.stop>
          <div class="nav-logo">
            <AtomsLocaleLink
              to="/home"
              @click="[handleMenuClose(), handleSendLog('BI')]"
            >
              <img
                :src="formatPathHost(biSmallPath)"
                :alt="gameName"
                class="h-[30px]"
              />
            </AtomsLocaleLink>
          </div>
          <nav :class="['nav-list', { 'is-mounted': isMounted }]">
            <template v-if="gnbMenusCount > 0">
              <div class="official custom-theme-scrollbar">
                <div
                  v-for="(gnbItem, key) in gnb?.menus"
                  :key="key"
                  class="nav-item group"
                  :class="{
                    'is-hidden':
                      breakpoints.isDesktop &&
                      overflowCount > 0 &&
                      Number(key) > gnbMenusCount - overflowCount,
                  }"
                >
                  <component
                    :is="isNotClickable(gnbItem) ? 'span' : 'AtomsLocaleLink'"
                    :to="gnbItem?.url_path"
                    :target="gnbItem?.link_target"
                    :class="[
                      'nav-1depth',
                      {
                        'router-link-active': hasActiveChild(gnbItem.children),
                      },
                    ]"
                    @click="handleGnbItemClick(gnbItem)"
                  >
                    <span>{{ gnbItem.menu_name }}</span>
                    <AtomsIconsWebLinkLine
                      v-if="gnbItem?.link_target === '_blank'"
                    />
                    <AtomsIconsArrowDownFill
                      v-if="has2depthButton(gnbItem)"
                      class="hidden md:block"
                    />
                    <AtomsIconsArrowRightLine
                      v-if="!has2depthButton(gnbItem)"
                      class="ml-auto md:hidden"
                    />
                  </component>
                  <Transition name="fade">
                    <div v-if="has2depthButton(gnbItem)" class="nav-2depth">
                      <ul>
                        <li
                          v-for="child in gnbItem.children"
                          :key="child.menu_name"
                        >
                          <component
                            :is="
                              isNotClickable(child) ? 'span' : 'AtomsLocaleLink'
                            "
                            :to="child.url_path"
                            :target="child.link_target"
                            class="item-link"
                            @click="handleGnbItemClick(child)"
                          >
                            <span>{{ child.menu_name }}</span>
                            <AtomsIconsWebLinkLine
                              v-if="child?.link_target === '_blank'"
                            />
                          </component>
                        </li>
                      </ul>
                    </div>
                  </Transition>
                </div>
              </div>
              <div v-if="overflowCount > 0" class="more group">
                <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 gnb?.menus"
                      :key="key"
                      :class="{
                        'is-hidden':
                          breakpoints.isDesktop &&
                          overflowCount > 0 &&
                          Number(key) <= gnbMenusCount - overflowCount,
                      }"
                    >
                      <component
                        :is="
                          isNotClickable(gnbItem) ? 'span' : 'AtomsLocaleLink'
                        "
                        :to="gnbItem?.url_path"
                        :target="gnbItem?.link_target"
                        :class="[
                          'nav-1depth',
                          'item-link',
                          {
                            'router-link-active': hasActiveChild(
                              gnbItem.children
                            ),
                          },
                        ]"
                        @click="handleGnbItemClick(gnbItem)"
                      >
                        <span>{{ gnbItem.menu_name }}</span>
                      </component>
                      <div v-if="gnbItem?.children">
                        <ul>
                          <li
                            v-for="child in gnbItem.children"
                            :key="child.menu_name"
                          >
                            <component
                              :is="
                                isNotClickable(child)
                                  ? 'span'
                                  : 'AtomsLocaleLink'
                              "
                              :to="child?.url_path"
                              :target="child?.link_target"
                              class="item-link"
                            >
                              <span>{{ child.menu_name }}</span>
                              <AtomsIconsWebLinkLine
                                v-if="child?.link_target === '_blank'"
                              />
                            </component>
                          </li>
                        </ul>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </template>
            <ClientOnly>
              <div v-if="eventBanner" class="event">
                <div class="nav-item">
                  <AtomsLocaleLink
                    :to="eventBanner?.page_url"
                    :target="eventBanner?.link_type === 1 ? '_self' : '_blank'"
                    :class="[
                      'nav-1depth',
                      { 'router-link-active': pageLayoutType === 'promotion' },
                    ]"
                    @click="[handleMenuClose(), handleSendLog('이벤트')]"
                  >
                    <span
                      class="flex items-center gap-1 flex-1 text-gradient-pink"
                    >
                      <AtomsIconsStarFill />
                      <span>{{ tm('Gnb_Event') }}</span>
                      <AtomsIconsStarFill />
                      <AtomsIconsArrowRightLine class="ml-auto md:hidden" />
                    </span>
                  </AtomsLocaleLink>
                </div>
              </div>
            </ClientOnly>
          </nav>
          <ClientOnly>
            <div ref="startRef" class="btn-start">
              <template v-if="start1depthData">
                <BlocksButtonLauncher
                  platform="pc"
                  variant="custom"
                  :background-color="
                    getColorCodeFromData(start1depthData?.btn_info, 'btn')
                  "
                  :text-color="
                    getColorCodeFromData(start1depthData?.btn_info, 'txt')
                  "
                  :use-game-font="
                    start1depthData?.btn_info?.use_game_font === 1
                  "
                  @click="handleSendLog(start1depthData.tracking)"
                >
                  {{ start1depthData?.btn_info?.txt_btn_name }}
                </BlocksButtonLauncher>
                <div
                  v-if="breakpoints.isDesktop && start2depthData"
                  class="nav-2depth"
                >
                  <ul>
                    <li v-for="(item, key) in start2depthData" :key="key">
                      <BlocksButtonLauncher
                        type="single"
                        variant="custom"
                        :platform="key"
                        @click="handleSendLog(item.tracking)"
                      >
                        {{ item.btn_info?.txt_btn_name }}
                      </BlocksButtonLauncher>
                    </li>
                  </ul>
                </div>
              </template>
            </div>
          </ClientOnly>
          <button class="btn-close" @click="handleMenuClose">
            <AtomsIconsCloseLine
              size="24"
              color="var(--foreground-reversal)"
              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 font-[500] tracking-[-0.48px] z-[200];
}
.game-wrap {
  @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-wrap.is-fixed {
  @apply fixed top-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];
}

.nav-wrap {
  @apply fixed top-0 left-0 bottom-0 w-0 mt-[var(--scroll-stove-position,48px)] md:relative md:w-full md:h-full md:mt-0;
}
.nav-wrap.is-open {
  @apply w-full;
}
.nav-wrap.is-open::before {
  @apply content-[''] absolute inset-0 w-[100vw] h-full bg-[rgba(0,0,0,0.6)] md:hidden;
}
.nav-wrap.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-[100%] 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-6 pl-2 pr-1
  md:flex-row md:order-none md:h-full md:my-0 md:ml-10 md:mr-6 md:px-0;
}
.nav-list.is-mounted {
  @apply md:overflow-visible;
}

.nav-list a {
  @apply transition-[background] hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10;
}
.nav-list a.nav-1depth:not(.item-link) {
  @apply md:hover:bg-transparent md:active:bg-transparent;
}

.nav-1depth.router-link-active {
  @apply bg-theme-foreground-reversal-8 md:bg-transparent;
}
.more-list .nav-1depth.router-link-active {
  @apply bg-theme-foreground-reversal-8;
}
.nav-item:hover .nav-1depth::after,
.nav-1depth.router-link-active::after {
  @apply opacity-100 md:transition-opacity;
}

.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-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-2depth {
  @apply text-[15px] group-hover:block 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 .item-link {
  @apply flex items-center gap-1 py-[9px] px-5 rounded-[12px]
  md:py-[11px] md:px-4;
}

.official {
  @apply overflow-x-hidden overflow-y-scroll pb-2 md:flex md:items-center md:space-x-8 md:pb-0 md:overflow-visible;
}
.custom-theme-scrollbar::-webkit-scrollbar {
  @apply w-1;
}
.custom-theme-scrollbar::-webkit-scrollbar-thumb {
  @apply border-0;
}

.more {
  @apply relative hidden ml-[32px] pt-[11px] 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 group-hover:block;
}
.list-inner {
  @apply min-w-[190px] p-3 rounded-[20px] bg-theme-foreground-10 shadow-lg;
}
.more-list .item-link {
  @apply flex items-center gap-1 py-[10px] px-4 rounded-[12px];
}
.more-list li .item-link {
  @apply px-6;
}
.more-list .nav-1depth {
  @apply after:hidden;
}

.official ~ .event {
  @apply md:ml-[64px]
  before:content-[''] before:block before:h-px before:mb-2 before:mx-3 before:bg-theme-foreground-reversal-8 md:before:hidden
  after:content-[''] 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%];
}
.event {
  @apply relative pr-1 md:pr-0;
}

.is-hidden {
  @apply hidden;
}

.btn-start {
  @apply relative py-2 px-5 md:absolute md:top-[0] md:right-0 md:flex md:items-center md:h-full md:py-0 md:px-0;
}
.btn-start:hover .nav-2depth {
  @apply md:block;
}
.btn-start:deep(.btn-base.default[data-variant='custom']) {
  @apply w-full h-[48px] px-10 font-[700] text-[16px];
}
.btn-start:deep(.btn-base.default[data-variant='custom']) .icon-platform {
  @apply hidden;
}

.btn-start .nav-2depth {
  @apply left-[unset] right-[-40px];
}
.btn-start .nav-2depth:deep(.btn-base) {
  @apply w-full h-[48px] px-4 
  hover:bg-theme-foreground-reversal-4 active:bg-theme-foreground-reversal-10;
}
.btn-start .nav-2depth:deep(.btn-base) .btn-content {
  @apply justify-start;
}
.btn-start .nav-2depth:deep(.btn-base) .icon-platform {
  @apply mr-1.5;
}
.btn-start .nav-2depth:deep(.btn-base) .text {
  @apply text-[15px] text-theme-foreground-reversal;
}

[data-theme='light'] {
  .btn-start .nav-2depth:deep(.btn-base) .icon-platform svg {
    @apply fill-[#1F1F1F];
  }
}
</style>
