<script setup>
import { AnimatePresence, motion } from 'motion-v'
import { ArrowRight, Languages, X } from 'lucide-vue-next'
import { resolvePublicUiValue } from '~/i18n/public-ui'
import { resolveBrowserPreferredPublicLocale } from '~/utils/public-browser-locale'
import { DEFAULT_PUBLIC_LOCALE, localizedExactPublicPath, normalizePublicLocale } from '~/utils/public-locales'
import { resolvePublicLocaleSwitchPath, usePublicLocaleSwitchContextState } from '~/composables/usePublicLocaleSwitchContext'

const route = useRoute()
const { locale: currentLocale } = usePublicLocale()
const localeSwitchContext = usePublicLocaleSwitchContextState()
const dismissed = ref(false)
const hydrated = ref(false)

const browserPreferredLocale = resolveBrowserPreferredPublicLocale()

const targetLocale = computed(() => {
  const browserLocale = normalizePublicLocale(browserPreferredLocale)
  const activeLocale = normalizePublicLocale(currentLocale.value)

  if (!browserLocale || browserLocale === activeLocale) {
    return ''
  }

  const context = localeSwitchContext.value
  const contextTarget = context?.pathsByLocale?.[browserLocale]
  const registryTarget = localizedExactPublicPath(route.path, browserLocale)

  if (context?.kind === 'detail' && !context.detailLocales?.includes(browserLocale) && !registryTarget) {
    return ''
  }

  if (contextTarget || registryTarget) {
    return browserLocale
  }

  return ''
})

const copyLocale = computed(() => targetLocale.value || normalizePublicLocale(currentLocale.value) || DEFAULT_PUBLIC_LOCALE)

const title = computed(() => resolvePublicUiValue(copyLocale.value, 'common.localizedVersionTitle', ''))
const description = computed(() => resolvePublicUiValue(copyLocale.value, 'common.localizedVersionDescription', ''))
const buttonLabel = computed(() => resolvePublicUiValue(copyLocale.value, 'common.localizedVersionButton', ''))

const targetHref = computed(() => {
  if (!targetLocale.value) {
    return ''
  }

  const context = localeSwitchContext.value
  const contextTarget = context ? resolvePublicLocaleSwitchPath(context, route.path, targetLocale.value) : ''
  const registryTarget = localizedExactPublicPath(route.path, targetLocale.value)

  return contextTarget || registryTarget || ''
})

const storageKey = computed(() => [
  'public-localized-version-banner',
  route.path,
  targetLocale.value || 'none',
].join(':'))

function readDismissed() {
  if (!import.meta.client) {
    return false
  }

  try {
    return window.localStorage.getItem(storageKey.value) === '1'
  }
  catch {
    return false
  }
}

function dismiss() {
  dismissed.value = true

  if (!import.meta.client) {
    return
  }

  try {
    window.localStorage.setItem(storageKey.value, '1')
  }
  catch {
    // ignore storage errors
  }
}

watch(
  storageKey,
  () => {
    if (!import.meta.client) {
      return
    }

    dismissed.value = readDismissed()
    hydrated.value = true
  },
  { immediate: true },
)

const shouldShow = computed(() => hydrated.value
  && Boolean(targetLocale.value)
  && Boolean(targetHref.value)
  && targetHref.value !== route.path
  && !dismissed.value
  && Boolean(title.value)
  && Boolean(description.value)
  && Boolean(buttonLabel.value),
)
</script>

<template>
  <AnimatePresence>
    <motion.div
      v-if="shouldShow"
      :initial="{ opacity: 0, y: 18, scale: 0.96 }"
      :animate="{ opacity: 1, y: 0, scale: 1 }"
      :exit="{ opacity: 0, y: 18, scale: 0.96 }"
      class="fixed bottom-4 right-4 z-50 w-[calc(100vw-2rem)] max-w-md pointer-events-none"
    >
      <div class="relative pointer-events-auto overflow-hidden rounded-[1.75rem] border border-white/70 bg-white/92 shadow-[0_24px_80px_rgba(15,23,42,0.16)] ring-1 ring-slate-900/5 backdrop-blur-2xl">
        <div class="absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(255,145,45,0.14),transparent_42%),radial-gradient(circle_at_bottom_right,rgba(15,23,42,0.04),transparent_38%)]" />
        <div class="relative h-1 bg-gradient-to-r from-transparent via-orange-400/80 to-transparent" />
        <div class="relative p-4 sm:p-5">
          <div class="flex items-start gap-3">
            <div class="flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-slate-900 text-white shadow-lg shadow-slate-900/10">
              <Languages class="h-5 w-5" />
            </div>

            <div class="min-w-0 flex-1">
              <div class="mb-2 flex items-center gap-2">
                <span class="inline-flex items-center rounded-full bg-orange-500/10 px-2.5 py-1 text-[10px] font-bold uppercase tracking-[0.22em] text-orange-600">
                  {{ copyLocale.toUpperCase() }}
                </span>
                <span class="text-[10px] font-semibold uppercase tracking-[0.24em] text-slate-400">
                  {{ currentLocale.toUpperCase() }}
                </span>
              </div>
              <h3 class="text-[15px] sm:text-base font-semibold text-slate-900 leading-snug">
                {{ title }}
              </h3>
              <p class="mt-1.5 text-sm text-slate-500 leading-relaxed">
                {{ description }}
              </p>
            </div>

            <button
              type="button"
              class="shrink-0 inline-flex h-8 w-8 items-center justify-center rounded-full border border-slate-200/80 bg-white/90 text-slate-400 transition-colors hover:bg-slate-50 hover:text-slate-900"
              @click="dismiss"
            >
              <X class="h-4 w-4" />
            </button>
          </div>

          <div class="mt-4 flex items-center justify-end">
            <NuxtLink
              :to="targetHref"
              class="inline-flex items-center gap-2 rounded-full bg-slate-900 px-4 py-2.5 text-[11px] font-bold uppercase tracking-[0.24em] text-white shadow-[0_10px_24px_rgba(15,23,42,0.18)] transition-all hover:-translate-y-0.5 hover:bg-slate-800"
            >
              <span>{{ buttonLabel }}</span>
              <ArrowRight class="h-4 w-4" />
            </NuxtLink>
          </div>
        </div>
      </div>
    </motion.div>
  </AnimatePresence>
</template>
