<script setup lang="ts">
import { useNuxtApp } from 'nuxt/app'
import type {
  GameDataMetaTag,
  GameDataValue,
  GameDataKeyColors,
  GameDataImg,
} from '#layers/types/api/gameData'

const nuxtApp = useNuxtApp()
const { locale } = useI18n()
const gameDataStore = useGameDataStore()
const modalStore = useModalStore()
const scrollStore = useScrollStore()

const { setGameData } = gameDataStore
const { confirm, alert } = modalStore
const { gameName, gaCode } = storeToRefs(gameDataStore)
const { scrollGnbPosition } = storeToRefs(scrollStore)

// favicon 링크 생성 헬퍼
const createStyleLinks = (faviconJson: GameDataImg, fontPath: string = '') => {
  const links = []
  const iconUrl = faviconJson[0]
  const appleTouchIconUrl = faviconJson[1]
  const pngIconUrl = faviconJson[2]

  if (iconUrl) {
    links.push({
      rel: 'icon',
      type: 'image/x-icon',
      href: formatPathHost(iconUrl),
    })
  }
  if (appleTouchIconUrl) {
    links.push({
      rel: 'apple-touch-icon',
      href: formatPathHost(appleTouchIconUrl),
    })
  }
  if (pngIconUrl) {
    links.push({
      rel: 'icon',
      type: 'image/png',
      href: formatPathHost(pngIconUrl),
    })
  }
  if (fontPath) {
    links.push({
      rel: 'stylesheet',
      href: formatPathHost(fontPath),
    })
  }

  return links
}

// 메타 태그 생성 헬퍼
const createMetaTags = (metaTag: Partial<GameDataMetaTag> = {}) => {
  const metaList = [
    { name: 'description', content: metaTag.page_desc },
    { property: 'og:title', content: metaTag.og_title },
    { property: 'og:description', content: metaTag.og_desc },
    {
      property: 'og:image',
      content: formatPathHost(metaTag.og_image),
    },
    { name: 'twitter:title', content: metaTag.x_title },
    { name: 'twitter:description', content: metaTag.x_desc },
    {
      name: 'twitter:image',
      content: formatPathHost(metaTag.x_image),
    },
  ]

  // content가 유효한 메타 태그만 필터링
  return metaList.filter(
    meta => meta.content && String(meta.content).trim() !== ''
  )
}

// CSS 변수 생성 헬퍼
const createStyleCss = (keyColorJson: GameDataKeyColors) => {
  const colorVariables = Object.entries(keyColorJson)
    .filter(([key, value]) => key && value != null)
    .map(([key, value]) => `--${key}: ${value};`)
    .join('\n      ')

  return `:root {${colorVariables}}`
}

// 게임 헤드 설정
const setupGameHead = (data: GameDataValue) => {
  try {
    const metaTag: Partial<GameDataMetaTag> = data.meta_tag_json ?? {}
    const designTheme = data.design_theme === 1 ? 'light' : 'dark'
    const styleLinks = createStyleLinks(
      data.favicon_json,
      data?.game_font_key_json?.font_path
    )
    const styleCss = createStyleCss(data.key_color_json)

    useHead({
      title: metaTag.page_title ?? '',
      meta: createMetaTags(metaTag),
      htmlAttrs: {
        'data-game': data.game_name ?? '',
        'data-theme': designTheme,
        lang: locale.value ?? data.default_lang_code ?? 'ko',
      },
      link: styleLinks,
      style: [
        {
          innerHTML: styleCss,
          id: 'game-css-variables',
        },
      ],
    })
  } catch (error) {
    // eslint-disable-next-line no-console
    console.error('[setupGameHead] Failed to setup game head:', error)
  }
}

if (import.meta.server) {
  const gameData = nuxtApp.ssrContext?.event?.context?.gameData
  if (gameData) {
    setGameData(gameData)
    setupGameHead(gameData)
  }
}

let rafId: number | null = null
let stopWatch: (() => void) | null = null

onMounted(() => {
  useEventListener('scroll', scrollStore.updateScrollValue, { passive: true })
  stopWatch = watch(
    scrollGnbPosition,
    newValue => {
      if (rafId) {
        cancelAnimationFrame(rafId)
      }
      rafId = requestAnimationFrame(() => {
        document.documentElement.style.setProperty(
          '--scroll-position',
          `${newValue}px`
        )
        rafId = null
      })
    },
    { immediate: true }
  )

  const { gtag, initialize } = useGtag()
  initialize(gaCode.value)
  gtag('event', 'screen_view', {
    app_name: 'My App',
    screen_name: 'Home',
  })
})

onBeforeUnmount(() => {
  // watch 정리
  if (stopWatch) {
    stopWatch()
    stopWatch = null
  }

  // requestAnimationFrame 정리
  if (rafId) {
    cancelAnimationFrame(rafId)
    rafId = null
  }
})
</script>

<template>
  <h1 class="sr-only">{{ gameName }}</h1>
  <NuxtPage />

  <!-- 공통 모달 컴포넌트 -->
  <WidgetsModalClient />
  <BlocksModalYouTube />
  <BlocksModalContent />
  <BlocksModalConfirm
    v-model:is-open="confirm.storeIsOpen"
    :is-show-dimmed="confirm.storeIsShowDimmed"
    :content-text="confirm.storeContentText"
    :confirm-button-text="confirm.storeConfirmButtonText"
    :cancel-button-text="confirm.storeCancelButtonText"
    :is-outside-close="confirm.storeIsOutsideClose"
    :modal-name="confirm.storeModalName"
    @confirm-button-event="confirm.storeConfirmButtonEvent"
    @cancel-button-event="confirm.storeCancelButtonEvent"
  />
  <BlocksModalAlert
    v-model:is-open="alert.storeIsOpen"
    :is-show-dimmed="alert.storeIsShowDimmed"
    :content-text="alert.storeContentText"
    :confirm-button-text="alert.storeConfirmButtonText"
    :is-outside-close="alert.storeIsOutsideClose"
    :modal-name="alert.storeModalName"
    @confirm-button-event="alert.storeConfirmButtonEvent"
  />
  <BlocksModalToast />

  <!-- 로딩 컴포넌트 -->
  <AtomsLoadingFull />
  <AtomsLoadingLocal />
</template>
