<script setup lang="ts">
import { ref, watch, onMounted, onUnmounted, nextTick } from 'vue'
import { useTourStore } from '../stores/tour'
import { getZoomFactor } from '../utils/dropdown'

const tourStore = useTourStore()

const spotlightStyle = ref<Record<string, string>>({})
const tooltipStyle = ref<Record<string, string>>({})
const tooltipRef = ref<HTMLElement | null>(null)

function positionElements() {
  const step = tourStore.currentStep
  if (!step) return

  const el = document.querySelector(step.target) as HTMLElement | null
  if (!el) {
    if (!tourStore.isLastStep) {
      tourStore.next()
    } else {
      tourStore.stop()
    }
    return
  }

  el.scrollIntoView({ behavior: 'smooth', block: 'center' })

  setTimeout(() => {
    const rect = el.getBoundingClientRect()
    const padding = 6
    const zoom = getZoomFactor()

    spotlightStyle.value = {
      top: `${(rect.top - padding) / zoom}px`,
      left: `${(rect.left - padding) / zoom}px`,
      width: `${(rect.width + padding * 2) / zoom}px`,
      height: `${(rect.height + padding * 2) / zoom}px`,
    }

    const placement = step.placement || 'bottom'
    const tooltipWidth = 280
    const tooltipGap = 12

    let top = 0
    let left = 0

    if (placement === 'bottom') {
      top = rect.bottom + tooltipGap
      left = rect.left + rect.width / 2 - tooltipWidth * zoom / 2
    } else if (placement === 'top') {
      top = rect.top - tooltipGap
      left = rect.left + rect.width / 2 - tooltipWidth * zoom / 2
    } else if (placement === 'right') {
      top = rect.top + rect.height / 2
      left = rect.right + tooltipGap
    } else if (placement === 'left') {
      top = rect.top + rect.height / 2
      left = rect.left - tooltipGap - tooltipWidth * zoom
    }

    left = Math.max(12, Math.min(left, window.innerWidth - tooltipWidth * zoom - 12))

    tooltipStyle.value = {
      top: placement === 'top' ? 'auto' : `${top / zoom}px`,
      bottom: placement === 'top' ? `${(window.innerHeight - top) / zoom}px` : 'auto',
      left: `${left / zoom}px`,
      width: `${tooltipWidth}px`,
    }

    // Focus the tooltip for screen readers
    nextTick(() => {
      if (tooltipRef.value) {
        tooltipRef.value.focus()
      }
    })
  }, 350)
}

watch(() => tourStore.currentStepIndex, () => {
  if (tourStore.isActive) {
    nextTick(() => positionElements())
  }
})

watch(() => tourStore.isActive, (active) => {
  if (active) {
    nextTick(() => positionElements())
  }
})

function onKeydown(e: KeyboardEvent) {
  if (!tourStore.isActive) return

  if (e.key === 'Escape') {
    e.preventDefault()
    tourStore.stop()
  } else if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
    e.preventDefault()
    tourStore.next()
  } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
    e.preventDefault()
    if (!tourStore.isFirstStep) tourStore.back()
  } else if (e.key === 'Tab') {
    // Trap focus within the tooltip
    if (!tooltipRef.value) return
    const focusable = tooltipRef.value.querySelectorAll('button')
    if (focusable.length === 0) return

    const first = focusable[0] as HTMLElement
    const last = focusable[focusable.length - 1] as HTMLElement

    if (e.shiftKey && document.activeElement === first) {
      e.preventDefault()
      last.focus()
    } else if (!e.shiftKey && document.activeElement === last) {
      e.preventDefault()
      first.focus()
    }
  }
}

function onResize() {
  if (tourStore.isActive) {
    positionElements()
  }
}

onMounted(() => {
  document.addEventListener('keydown', onKeydown)
  window.addEventListener('resize', onResize)
})

onUnmounted(() => {
  document.removeEventListener('keydown', onKeydown)
  window.removeEventListener('resize', onResize)
})
</script>

<template>
  <Teleport to="#app">
    <Transition name="tour-fade">
      <div
        v-if="tourStore.isActive"
        class="fixed inset-0 z-[9998]"
        role="dialog"
        aria-modal="true"
        :aria-label="'Feature tour: step ' + (tourStore.currentStepIndex + 1) + ' of ' + tourStore.totalSteps"
      >
        <!-- Backdrop - click to dismiss -->
        <div
          class="absolute inset-0"
          @click="tourStore.stop()"
          aria-hidden="true"
        />

        <!-- Spotlight cutout -->
        <div
          class="absolute rounded-md pointer-events-none transition-all duration-300 ease-out"
          :style="spotlightStyle"
          style="box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.6);"
          aria-hidden="true"
        />

        <!-- Tooltip card -->
        <div
          ref="tooltipRef"
          tabindex="-1"
          class="absolute z-[9999] bg-bg-surface border border-border-subtle rounded-lg shadow-lg p-4 pointer-events-auto transition-all duration-300 ease-out focus:outline-none"
          :style="tooltipStyle"
        >
          <p class="text-[0.8125rem] font-medium text-text-primary mb-1" aria-live="polite">
            {{ tourStore.currentStep?.title }}
          </p>
          <p class="text-[0.75rem] text-text-secondary leading-relaxed mb-3">
            {{ tourStore.currentStep?.content }}
          </p>

          <div class="flex items-center justify-between">
            <span class="text-[0.6875rem] text-text-tertiary" aria-hidden="true">
              {{ tourStore.currentStepIndex + 1 }} / {{ tourStore.totalSteps }}
            </span>
            <div class="flex items-center gap-2" role="group" aria-label="Tour navigation">
              <button
                @click="tourStore.stop()"
                class="px-2.5 py-1 text-[0.6875rem] text-text-tertiary hover:text-text-secondary transition-colors duration-150 rounded focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
              >
                Skip
              </button>
              <button
                v-if="!tourStore.isFirstStep"
                @click="tourStore.back()"
                class="px-2.5 py-1 text-[0.6875rem] border border-border-subtle text-text-secondary rounded-md hover:bg-bg-elevated transition-colors duration-150 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent"
              >
                Back
              </button>
              <button
                @click="tourStore.next()"
                class="px-3 py-1 text-[0.6875rem] bg-accent text-bg-base font-medium rounded-md hover:bg-accent-hover transition-colors duration-150 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
              >
                {{ tourStore.isLastStep ? 'Done' : 'Next' }}
              </button>
            </div>
          </div>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>
