/**
 * useTtsPlayback — central hook for TTS audio playback.
 *
 * Plays base64-encoded audio (MP3), manages current playback state,
 * emits lifecycle events. Used by all features (CommCoach, Workspace, etc.).
 */

import { useCallback, useRef, useState } from 'react';

export type TtsEvent = 'playing' | 'paused' | 'ended' | 'error';

export interface TtsPlaybackCallbacks {
  onPlaying?: () => void;
  onPaused?: () => void;
  onEnded?: () => void;
  onError?: () => void;
}

export interface TtsPlaybackApi {
  isPlaying: boolean;
  isPaused: boolean;
  play: (base64Audio: string, format?: string) => void;
  pause: () => void;
  resume: () => void;
  stop: () => void;
}

export function useTtsPlayback(callbacks?: TtsPlaybackCallbacks): TtsPlaybackApi {
  const [isPlaying, setIsPlaying] = useState(false);
  const [isPaused, setIsPaused] = useState(false);
  const audioRef = useRef<HTMLAudioElement | null>(null);
  const cbRef = useRef(callbacks);
  cbRef.current = callbacks;

  const _emit = useCallback((event: TtsEvent) => {
    if (event === 'playing') { setIsPlaying(true); setIsPaused(false); cbRef.current?.onPlaying?.(); }
    else if (event === 'paused') { setIsPaused(true); cbRef.current?.onPaused?.(); }
    else if (event === 'ended') { setIsPlaying(false); setIsPaused(false); cbRef.current?.onEnded?.(); }
    else if (event === 'error') { setIsPlaying(false); setIsPaused(false); cbRef.current?.onError?.(); }
  }, []);

  const stop = useCallback(() => {
    if (audioRef.current) {
      audioRef.current.pause();
      audioRef.current = null;
    }
    setIsPlaying(false);
    setIsPaused(false);
  }, []);

  const play = useCallback((base64Audio: string, format?: string) => {
    if (!base64Audio) return;
    stop();
    try {
      const mimeType = format === 'wav' ? 'audio/wav' : 'audio/mp3';
      const audio = new Audio(`data:${mimeType};base64,${base64Audio}`);
      audioRef.current = audio;
      audio.onended = () => { audioRef.current = null; _emit('ended'); };
      audio.onpause = () => { if (audioRef.current === audio && audio.currentTime < audio.duration) _emit('paused'); };
      audio.play().then(() => _emit('playing')).catch(() => _emit('error'));
    } catch {
      _emit('error');
    }
  }, [stop, _emit]);

  const pause = useCallback(() => {
    if (audioRef.current && !audioRef.current.paused) {
      audioRef.current.pause();
    }
  }, []);

  const resume = useCallback(() => {
    if (audioRef.current && audioRef.current.paused) {
      audioRef.current.play().then(() => _emit('playing')).catch(() => _emit('error'));
    }
  }, [_emit]);

  return { isPlaying, isPaused, play, pause, resume, stop };
}
