<template>
  <div
    class="grid h-full sm:grid-rows-[auto_1fr_auto] grid-rows-[1fr_auto_auto] overflow-hidden touch-none"
  >
    <!-- Content Section -->
    <div
      class="flex overflow-hidden overflow-y-auto pb-safe-or-4 sm:pt-safe px-4 overscroll-contain touch-manipulation"
      ref="contentScrollContainer"
    >
      <div class="sm:max-w-prose grid grid-cols-1 mx-auto my-5 w-full">
        <slot name="default" v-bind:scrollToBottom />
      </div>
    </div>

    <!-- Footer Section -->
    <slot name="footer">
      <footer
        v-if="!slots.footer"
        class="bg-gray-100 dark:bg-gray-800 text-center py-1.5 border-t dark:border-gray-700 text-xs sm:text-base text-gray-700 dark:text-gray-300 sm:order-last sm:pb-safe-or-1.5"
      >
        <span class="text-nowrap">Сделайте НаСвязи удобнее.</span>
        <span> </span>
        <span class="text-nowrap">
          Будем рады
          <RouterLink
            to="/donate"
            class="underline underline-offset-2 text-primary-600 dark:text-primary-400"
          >
            вашей поддержке
          </RouterLink>
        </span>
      </footer>
    </slot>

    <!-- TabBar -->
    <TabBar />
  </div>
</template>

<script setup lang="ts">
import { useTemplateRef } from 'vue'

const slots = defineSlots<{
  default?: (slotBindings: { scrollToBottom: typeof scrollToBottom }) => void
  footer?: () => void
}>()

const contentScrollContainerRef = useTemplateRef('contentScrollContainer')

const scrollToBottom = () => {
  if (contentScrollContainerRef.value) {
    contentScrollContainerRef.value.scrollTop = contentScrollContainerRef.value.scrollHeight
  }
}

// Устанавливаем корректную высоту при загрузке и изменении размера окна
const onresize = () => {
  document.documentElement.style.setProperty(
    '--visual-viewport-offset-top',
    `${visualViewport!.offsetTop!}px`,
  )
  document.documentElement.style.setProperty(
    '--visual-viewport-height',
    `${visualViewport!.height}px`,
  )
  if (document.activeElement) {
    if ('scrollIntoViewIfNeeded' in document.activeElement) {
      ;(document.activeElement.scrollIntoViewIfNeeded as (options?: ScrollIntoViewOptions) => void)(
        {
          block: 'center',
        },
      )
    } else {
      document.activeElement.scrollIntoView({ block: 'center' })
    }
  }
}

function preventScroll(e: TouchEvent) {
  if (
    contentScrollContainerRef.value &&
    contentScrollContainerRef.value.scrollHeight <= contentScrollContainerRef.value.clientHeight
  ) {
    e.preventDefault()
  }
}

const layoutPageHead = useHead({
  htmlAttrs: { class: 'overflow-hidden overscroll-none touch-none fix-layout-scrolling' },
  bodyAttrs: { class: 'overflow-hidden overscroll-none touch-none' },
})

onMounted(() => {
  visualViewport?.addEventListener('resize', onresize, { passive: true })
  contentScrollContainerRef.value!.addEventListener('touchmove', preventScroll, { passive: false })
})

onBeforeUnmount(() => {
  layoutPageHead?.dispose()
  visualViewport?.removeEventListener('resize', onresize)
  document.documentElement.style.removeProperty('--visual-viewport-offset-top')
  document.documentElement.style.removeProperty('--visual-viewport-height')
  contentScrollContainerRef.value!.removeEventListener('touchmove', preventScroll)
})
</script>

<style scoped>
::v-global(html.fix-layout-scrolling) {
  --visual-viewport-height: 100dvh;
  --visual-viewport-offset-top: 0px;
  position: fixed;
  width: 100dvw;
  height: var(--visual-viewport-height);
  top: var(--visual-viewport-offset-top);
  bottom: 0;
}
</style>
