export interface NarratorSettings {
  enabled: boolean
  rate: number
  pitch: number
  voice: string
  verbosity: 'brief' | 'normal' | 'verbose'
  mode: 'voice' | 'screenreader' | 'both'
  sounds: boolean
}

export const defaultNarratorSettings: NarratorSettings = {
  enabled: false,
  rate: 1.0,
  pitch: 1.0,
  voice: '',
  verbosity: 'normal',
  mode: 'voice',
  sounds: true,
}

let settings: NarratorSettings = { ...defaultNarratorSettings }

export function updateSettings(s: NarratorSettings) {
  settings = s
}

export function isSupported(): boolean {
  return 'speechSynthesis' in window
}

export function getVoices(): SpeechSynthesisVoice[] {
  if (!isSupported()) return []
  return window.speechSynthesis.getVoices()
}

export function cancel() {
  if (!isSupported()) return
  window.speechSynthesis.cancel()
}

// a polite live region that screen readers announce from, created on demand
let srRegion: HTMLElement | null = null

function getSrRegion(): HTMLElement {
  if (!srRegion) {
    srRegion = document.createElement('div')
    srRegion.setAttribute('aria-live', 'polite')
    srRegion.setAttribute('role', 'status')
    srRegion.className = 'visually-hidden'
    document.body.appendChild(srRegion)
  }
  return srRegion
}

function announceToScreenReader(text: string) {
  const region = getSrRegion()
  const msg = document.createElement('span')
  msg.textContent = `${text} `
  region.appendChild(msg)
  while (region.children.length > 6) {
    const first = region.firstChild
    if (first) region.removeChild(first)
  }
  setTimeout(() => msg.remove(), 15000)
}

export function speak(text: string, interrupt = true) {
  if (!settings.enabled) return

  const mode = settings.mode
  const wantsVoice = (mode === 'voice' || mode === 'both') && isSupported()
  const wantsSr = mode === 'screenreader' || mode === 'both' || !isSupported()

  if (wantsSr) announceToScreenReader(text)
  if (!wantsVoice) return

  if (interrupt) cancel()

  const utterance = new SpeechSynthesisUtterance(text)
  utterance.rate = settings.rate
  utterance.pitch = settings.pitch

  if (settings.voice) {
    const voices = getVoices()
    const match = voices.find(v => v.name === settings.voice)
    if (match) utterance.voice = match
  }

  window.speechSynthesis.speak(utterance)
}

// voices load async - call this early so they're ready
export function preloadVoices() {
  if (!isSupported()) return
  getVoices()
}

preloadVoices()