<script setup lang="ts">
import type { PageDataLnbMenu } from '#layers/types/api/pageData'

const { y: windowY } = useWindowScroll({ behavior: 'smooth' })
const pageDataStore = usePageDataStore()
const breakpoints = useResponsiveBreakpoints()

const { pageData } = storeToRefs(pageDataStore)

const observerOptions = {
  root: null,
  rootMargin: '-20% 0px -60% 0px', // 상단 20%, 하단 60% 마진
  threshold: 0,
}
const activeSection = ref<string>('')

const lnbList = computed<Record<string, PageDataLnbMenu>>(
  () => pageData.value?.lnb_menus || {}
)
const isShowLnb = computed(() => {
  return Boolean(
    pageData.value?.use_lnb &&
      breakpoints.value.isDesktop &&
      Object.keys(lnbList.value).length > 0
  )
})
const activeColor = computed(
  () => pageData.value?.lnb_text_color_code_active || 'var(--text-primary)'
)
const disableColor = computed(
  () => pageData.value?.lnb_text_color_code_deactive || 'var(--text-secondary)'
)

// 1depth가 활성화되었는지 확인 (자신 또는 자식 중 하나가 활성화된 경우)
const is1DepthActive = (lnbItem: PageDataLnbMenu): boolean => {
  // 자신이 활성화된 경우
  if (activeSection.value === lnbItem.page_ver_tmpl_name_en) {
    return true
  }

  // children 중 하나가 활성화된 경우
  if (lnbItem.children && Object.keys(lnbItem.children).length > 0) {
    return Object.values(lnbItem.children).some(
      child => activeSection.value === child.page_ver_tmpl_name_en
    )
  }

  return false
}

const observer = new IntersectionObserver(entries => {
  if (import.meta.server) return
  // 교차하는 섹션들 중 가장 위에 있는 것을 활성화
  const visibleEntries = entries
    .filter(entry => entry.isIntersecting)
    .sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top)

  if (visibleEntries.length > 0) {
    activeSection.value = visibleEntries[0].target.id
  }
}, observerOptions)

const observeSections = () => {
  if (import.meta.server) return
  Object.values(lnbList.value).forEach(lnbItem => {
    // 1depth 관찰
    const el = document.getElementById(lnbItem.page_ver_tmpl_name_en)
    if (el) {
      observer.observe(el)
    }

    // 2depth 관찰
    if (lnbItem.children && Object.keys(lnbItem.children).length > 0) {
      Object.values(lnbItem.children).forEach(childItem => {
        const childEl = document.getElementById(childItem.page_ver_tmpl_name_en)
        if (childEl) {
          observer.observe(childEl)
        }
      })
    }
  })
}

const handleLnbClick = (lnbItem: PageDataLnbMenu) => {
  if (import.meta.server) return

  const id = lnbItem.page_ver_tmpl_name_en
  const el = document.getElementById(id)
  if (!el) return

  const elementTop = el.getBoundingClientRect().top
  const currentScrollY = window.scrollY
  const headerHeight = 64
  const targetScrollY = currentScrollY + elementTop - headerHeight

  windowY.value = targetScrollY
}

onMounted(() => {
  observeSections()
})

onUnmounted(() => {
  observer.disconnect()
})
</script>

<template>
  <div
    v-if="isShowLnb"
    class="lnb-wrap"
    :style="{
      '--lnb-active-color': activeColor,
      '--lnb-disable-color': disableColor,
    }"
  >
    <ul class="main-list">
      <li v-for="lnbItem in lnbList" :key="lnbItem.path_code">
        <button
          v-dompurify-html="lnbItem.menu_name"
          type="button"
          :class="['btn-1depth', { 'is-active': is1DepthActive(lnbItem) }]"
          @click="handleLnbClick(lnbItem)"
        ></button>
        <ul
          v-if="Object.keys(lnbItem.children || {}).length > 0"
          class="sub-list"
        >
          <li v-for="subItem in lnbItem.children" :key="subItem.path_code">
            <button
              v-dompurify-html="subItem.menu_name"
              type="button"
              :class="[
                'btn-2depth',
                {
                  'is-active': activeSection === subItem.page_ver_tmpl_name_en,
                },
              ]"
              @click="handleLnbClick(subItem)"
            ></button>
          </li>
        </ul>
      </li>
    </ul>
  </div>
</template>

<style scoped>
.lnb-wrap {
  @apply fixed top-1/2 right-0 py-12 pr-[42px] text-right -translate-y-1/2 bg-[radial-gradient(100%_50%_at_100%_50%,rgba(0,0,0,0.5)_25%,rgba(0,0,0,0)_100%)] z-50;
}
.main-list {
  @apply flex flex-col gap-4 items-end;
}
.btn-1depth {
  @apply text-[15px] leading-[26px] tracking-[-0.54px];
}
.sub-list {
  @apply flex flex-col gap-2 items-end mt-4 mb-1 pr-[46px];
}
.btn-2depth {
  @apply text-[14px] leading-[20px] tracking-[-0.42px];
}

button {
  @apply relative font-[500] text-[var(--lnb-disable-color)] transition-all duration-300 ease-in-out;
}
button:hover,
button.is-active {
  @apply text-[var(--lnb-active-color)];
}
button::before {
  @apply content-[''] absolute top-1/2 rounded-full -translate-y-1/2 bg-transparent transition-all duration-300 ease-in-out;
}
button.is-active::before {
  @apply bg-[var(--lnb-active-color)];
}
.btn-1depth::before {
  @apply -right-4 w-1.5 h-1.5;
}
.btn-2depth::before {
  @apply -right-3.5 w-1 h-1;
}
</style>
