<script setup lang="ts">
import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock'

import { PAGES } from '#adata-ui/shared/constans/pages'
import ProductMenu from '#adata-ui/components/navigation/header/ProductMenu.vue'

import ContactMenu from '#adata-ui/components/navigation/header/ContactMenu.vue'
import { buildLocalizedUrl } from '#adata-ui/utils/localizedNavigation'

const { myLayer }: any = useAppConfig()
const { t, locale } = useI18n()

const navs: any = [
  {
    label: 'header.navs.products',
    to: myLayer.landingUrl + PAGES.totalServices
  },
  {
    label: 'header.navs.contacts',
    to: myLayer.landingUrl + PAGES.contacts
  },
  {
    label: 'header.navs.tariffs',
    to: myLayer.landingUrl + PAGES.tariffs
  }
]

const menu = ref<HTMLElement | null>(null)
const isBodyAlreadyLocked = ref<boolean>(false)
const currentIndex = ref(0)
const forward = ref(true)
const show = ref(false)
const isMenuLocked = ref(false)
const animation = ref('slide-fade')
const currentMenu = shallowRef(null)
const delayTimer = ref<ReturnType<typeof setTimeout> | null>(null)

const currentMenuToShow = (index) => {
  switch (index) {
    case 0:
      return ProductMenu
    case 1:
      return ContactMenu
    case 2:
      return null
  }
}
const toggleMenu = (index: number) => {
  if (index === 2) {
    window.open(buildLocalizedUrl(locale, myLayer.landingUrl, PAGES.tariffs), '_blank')
  } else {
    currentMenu.value = currentMenuToShow(index)
    const prev = currentIndex.value
    if (prev < index) {
      forward.value = false
    } else if (prev > index) {
      forward.value = true
    }
    animation.value = forward.value ? ' prev' : 'next'
    if (!show.value) animation.value = 'slide-fade'
    currentIndex.value = index
    show.value = true
  }
}
const closeMenu = (forceClose = false) => {
  if (isMenuLocked.value && !forceClose) {
    return
  } else {
    animation.value = 'slide-fade'
    show.value = false

    setTimeout(() => {
      isMenuLocked.value = false
      currentMenu.value = null
    }, 200)
  }
}
const onMenuMouseEnter = (index: number) => {
  if (index !== 2) {
    if (show.value === false) {
      delayTimer.value = setTimeout(() => {
        toggleMenu(index)
      }, 600)
    } else {
      delayTimer.value = setTimeout(() => {
        toggleMenu(index)
      }, 100)
    }
  } else show.value = false
}
const onMenuMouseLeave = () => {
  if (delayTimer.value) {
    clearTimeout(delayTimer.value)
    delayTimer.value = null
  }
}
const lockMenu = () => {
  isMenuLocked.value = true
}
const toggleBodyScroll = (el: HTMLBodyElement | HTMLDivElement, lock: boolean) => {
  if (lock) {
    setTimeout(() => {
      disableBodyScroll(el, { reserveScrollBarGap: true })
    }, 0)
    return
  }
  enableBodyScroll(el)
}

onBeforeUnmount(() => {
  if (show.value) toggleBodyScroll(menu.value, false)
})

watch(
  () => [show.value, menu.value],
  (newVal, oldVal) => {
    const wasShown = oldVal ? oldVal[0] : false
    const [isShown, menuEl] = newVal
    const isOpening = isShown
    const isClosing = wasShown && !isShown

    if (!menuEl) return
    if (isOpening) isBodyAlreadyLocked.value = !!document.body.style.overflow

    if (isShown) {
      toggleBodyScroll(menuEl, true)
      return
    }

    if (!isClosing || isBodyAlreadyLocked.value) return

    setTimeout(() => {
      if (menuEl) toggleBodyScroll(menuEl, false)
    }, 100)
  }
)
</script>

<template>
  <div class="relative">
    <ul>
      <li
        v-for="(nav, index) in navs"
        :key="nav.label"
        class="group inline-block border-r border-[#2C3E501A] px-2 last-of-type:border-none dark:border-[#E3E5E81A]"
        @click="lockMenu"
      >
        <div
          class="relative cursor-pointer font-bold uppercase text-gray-800 hover:text-gray-600 dark:text-gray-200 hover:dark:text-gray-600"
          @mouseenter="onMenuMouseEnter(index)"
          @click="toggleMenu(index)"
          @mouseleave="onMenuMouseLeave"
        >
          {{ t(nav.label) }}
        </div>
      </li>
    </ul>
    <div
      v-show="show"
      ref="menu"
      class="mt-5 fixed left-0 z-20 h-full w-full"
    >
      <div class="h-full w-full">
        <transition :name="animation">
          <keep-alive>
            <component
              :is="currentMenu"
              v-show="show"
              :animation="forward ? 'next' : 'prev'"
              :index="currentIndex"
              :url="buildLocalizedUrl(locale, myLayer.landingUrl, PAGES.contacts)"
              @outer-click="closeMenu(true)"
              @mouse-over="closeMenu"
            />
          </keep-alive>
        </transition>
        <div
          v-show="show"
          class="absolute left-[-25%] h-full w-[150%] bg-[#E3E5E833] backdrop-blur transition"
          @click="closeMenu(true)"
          @mouseover="closeMenu(false)"
        />
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
$percent: 30%;
.next-enter-from,
.next-leave-to {
  opacity: 0;
  transform: translateX($percent);
  position: absolute;
}

.next-enter-active {
  transition: all 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.next-leave-active {
  transition: all 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  opacity: 0;
  transform: translateX(-$percent);
}

// Backwards transition

.prev-enter-from,
.prev-leave-to {
  position: absolute;

  opacity: 0;
  transform: translateX(-$percent);
}

.prev-enter-active {
  transition: all 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.prev-leave-active {
  transition: all 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  opacity: 0;
  transform: translateX($percent);
}

.slide-fade-enter-active,
.slide-fade-leave-active {
  transition: all 0.2s ease-in-out;
}

.slide-fade-enter-from,
.slide-fade-leave-to {
  transform: translateY(-12px);
  opacity: 0;
}

.slide-change-enter-active,
.slide-change-leave-active {
  transition: all 0.2s ease-in-out;
}

.slide-change-enter-from,
.slide-change-leave-to {
  opacity: 0;
}
</style>
