(function(){
  'use strict';

  if (window.VMOAudioCoordinator) return; // singleton

  const Coordinator = {
    isSpeaking: false,
    activeRecognizer: null, // module id that currently owns the mic
    ttsOwner: null,
    ttsAllowBargeInMonitor: false,

    stopAllTTS(reason = 'stop', source = 'unknown') {
      // Best-effort stop of any plugin-controlled audio
      try {
        const container = document.getElementById('vmo-tts-container');
        if (container) {
          const audios = container.querySelectorAll('audio');
          audios.forEach(a => {
            // Allow the TTS client to abort in-flight requests/streams if it provided a hook
            try { typeof a.vmoStop === 'function' && a.vmoStop(reason); } catch(_) {}
            try { a.pause(); } catch(_) {}
            try { a.currentTime = 0; } catch(_) {}
            try { a.removeAttribute('src'); } catch(_) {}
            try { a.load(); } catch(_) {}
            try { a.remove(); } catch(_) {}
          });
        }
      } catch(_) {}

      try { window.speechSynthesis && window.speechSynthesis.cancel(); } catch(_) {}

      this.isSpeaking = false;
      try {
        window.dispatchEvent(new CustomEvent('vmo:tts-stopped', { detail: { reason, source } }));
      } catch(_) {}
    },

    requestMic(moduleId, options) {
      if (!moduleId) moduleId = 'unknown';
      const opts = options && typeof options === 'object' ? options : {};
      const bargeIn = !!opts.bargeIn;
      // Block mic while TTS is speaking
      if (this.isSpeaking) {
        if (bargeIn) {
          try { this.stopAllTTS('barge-in', moduleId); } catch(_) {}
        } else {
          console.warn('[VMOAudioCoordinator] Mic request denied - TTS is speaking', { moduleId });
          return false;
        }
      }
      if (this.activeRecognizer && this.activeRecognizer !== moduleId) {
        // Ask previous owner to relinquish the mic
        try {
          window.dispatchEvent(new CustomEvent('vmo:mic-revoke', { detail: { from: this.activeRecognizer, to: moduleId } }));
        } catch(_) {}
      }
      this.activeRecognizer = moduleId;
      return true;
    },

    releaseMic(moduleId) {
      if (!moduleId) moduleId = 'unknown';
      if (this.activeRecognizer === moduleId) {
        this.activeRecognizer = null;
      }
    },

    onTTSStart(source, options) {
      this.isSpeaking = true;

      const opts = options && typeof options === 'object' ? options : {};
      const moduleId = (typeof opts.moduleId === 'string' && opts.moduleId) ? opts.moduleId : null;
      const allowBargeInMonitor = !!opts.allowBargeInMonitor;

      this.ttsOwner = moduleId || source || null;
      this.ttsAllowBargeInMonitor = allowBargeInMonitor;

      // Revoke mic from any active recognizer unless the same module explicitly
      // requests barge-in monitoring during its own TTS.
      if (this.activeRecognizer) {
        if (allowBargeInMonitor && moduleId && this.activeRecognizer === moduleId) {
          return;
        }
        try {
          window.dispatchEvent(new CustomEvent('vmo:mic-revoke', { detail: { from: this.activeRecognizer, reason: 'tts', source: source || 'tts' } }));
        } catch(_) {}
        this.activeRecognizer = null;
      }
    },

    onTTSStop() {
      this.isSpeaking = false;
      this.ttsOwner = null;
      this.ttsAllowBargeInMonitor = false;
    }
    ,

    // Backward-compat: some modules call stopSpeaking() to clear TTS locks
    stopSpeaking() {
      this.onTTSStop();
    }
  };

  window.VMOAudioCoordinator = Coordinator;
  console.log('✅ VMO Audio Coordinator ready');
})();
