import type { NarratorContext, HeroType } from './useFetchNarratorText'

interface NarratorMessage {
  context: NarratorContext
  priority: number
}

const HINT_COOLDOWN = 120000

const isVisible = ref(false)
const currentMessage = ref('')
const messageQueue = ref<NarratorMessage[]>([])
const isProcessing = ref(false)
const shownEncouragements = ref<Set<number>>(new Set())
const lastHintTime = ref(0)

export function useNarrator() {
  const { fetchText } = useFetchNarratorText()
  const progressionStore = useProgressionStore()

  async function queueMessage(context: NarratorContext, priority: number = 5) {
    messageQueue.value.push({ context, priority })
    messageQueue.value.sort((a, b) => b.priority - a.priority)

    if (!isProcessing.value) {
      processQueue()
    }
  }

  async function processQueue() {
    if (messageQueue.value.length === 0) {
      isProcessing.value = false
      return
    }

    isProcessing.value = true
    const next = messageQueue.value.shift()!

    try {
      const heroType = progressionStore.hero as HeroType | undefined
      const response = await fetchText(next.context, heroType ?? undefined)
      if (response) {
        currentMessage.value = response.text
        isVisible.value = true
      } else {
        processQueue()
      }
    } catch {
      processQueue()
    }
  }

  function hide() {
    isVisible.value = false
    setTimeout(() => {
      processQueue()
    }, 300)
  }

  async function showIntro() {
    if (progressionStore.hasExistingProgress) {
      await queueMessage('welcome_back', 10)
    } else {
      await queueMessage('intro', 10)
    }
  }

  async function showTransition(zone: 'projects' | 'skills' | 'testimonials' | 'journey') {
    const contextMap: Record<string, NarratorContext> = {
      projects: 'transition_projects',
      skills: 'transition_skills',
      testimonials: 'transition_testimonials',
      journey: 'transition_journey',
    }
    await queueMessage(contextMap[zone], 7)
  }

  async function showEncouragement(percent: number) {
    let context: NarratorContext | null = null

    if (percent >= 75 && !shownEncouragements.value.has(75)) {
      context = 'encouragement_75'
      shownEncouragements.value.add(75)
    } else if (percent >= 50 && !shownEncouragements.value.has(50)) {
      context = 'encouragement_50'
      shownEncouragements.value.add(50)
    } else if (percent >= 25 && !shownEncouragements.value.has(25)) {
      context = 'encouragement_25'
      shownEncouragements.value.add(25)
    }

    if (context) {
      await queueMessage(context, 5)
    }
  }

  async function showHint() {
    const now = Date.now()
    if (now - lastHintTime.value < HINT_COOLDOWN) return

    lastHintTime.value = now
    await queueMessage('hint', 3)
  }

  async function showContactUnlocked() {
    await queueMessage('contact_unlocked', 8)
  }

  return {
    isVisible: readonly(isVisible),
    currentMessage: readonly(currentMessage),
    hide,
    showIntro,
    showTransition,
    showEncouragement,
    showHint,
    showContactUnlocked,
  }
}
