interface SpeechLike {
  text: string;
  lang: string;
  rate: number;
  volume: number;
  voice?: { lang: string; name?: string } | null;
  onend: (() => void) | null;
  onerror: ((event: { error?: string }) => void) | null;
}

interface SpeechEngine {
  getVoices(): Array<{ lang: string; name?: string }>;
  speak(value: SpeechLike): void;
  pause(): void;
  resume(): void;
  cancel(): void;
}

export function createSpeechFallback(dependencies: {
  engine?: SpeechEngine;
  Utterance?: new (text: string) => SpeechLike;
} = {}) {
  const engine = dependencies.engine ?? window.speechSynthesis as unknown as SpeechEngine;
  const Utterance = dependencies.Utterance ?? SpeechSynthesisUtterance as unknown as new (text: string) => SpeechLike;
  return {
    speak(input: { text: string; language: "zh-CN" | "en-US"; rate: number; volume?: number }): Promise<void> {
      engine.cancel();
      return new Promise((resolve, reject) => {
        const utterance = new Utterance(input.text);
        utterance.lang = input.language;
        utterance.rate = Math.min(3, Math.max(0.5, input.rate));
        utterance.volume = Math.min(1, Math.max(0, input.volume ?? 1));
        utterance.voice = engine.getVoices().find((voice) => voice.lang.toLowerCase().startsWith(input.language.toLowerCase())) ?? null;
        utterance.onend = resolve;
        utterance.onerror = (event) => reject(new Error(event.error || "浏览器朗读失败。"));
        engine.speak(utterance);
      });
    },
    pause: () => engine.pause(),
    resume: () => engine.resume(),
    cancel: () => engine.cancel(),
  };
}
