export function createNotesRecorder(options) {
  options = options || {};
  var recorder = null;
  var recTimer = null;
  var recPaused = false;
  var recActive = false;

  function start() {
    if (recActive) return;
    if (typeof options.ensureEditor === 'function') options.ensureEditor();
    if (typeof AudioRecorder === 'undefined') { updateStatus('Recorder unavailable', 'err'); return; }
    recorder = new AudioRecorder();
    recorder.start().then(function() {
      recActive = true; recPaused = false;
      setUI('recording');
      startTimer();
    }).catch(function(err) {
      updateStatus('Mic denied: ' + (err && err.message || ''), 'err');
    });
  }

  function togglePause() {
    if (!recActive || !recorder || !recorder.mediaRecorder) return;
    if (!recPaused) {
      try { recorder.mediaRecorder.pause(); } catch (e) {}
      recPaused = true; stopTimer(); setUI('paused');
    } else {
      try { recorder.mediaRecorder.resume(); } catch (e) {
        try {
          if (recorder.stream && recorder.stream.active) {
            var mime = MediaRecorder.isTypeSupported('audio/webm;codecs=opus') ? 'audio/webm;codecs=opus' : 'audio/webm';
            recorder.mediaRecorder = new MediaRecorder(recorder.stream, { mimeType: mime, audioBitsPerSecond: 32000 });
            recorder.mediaRecorder.ondataavailable = function(ev) { if (ev.data.size > 0) recorder.chunks.push(ev.data); };
            recorder.mediaRecorder.start(1000);
          }
        } catch (e2) {}
      }
      recPaused = false; startTimer(); setUI('recording');
    }
  }

  function stop(silent) {
    if (!recActive || !recorder) {
      if (!silent) setUI('idle');
      return;
    }
    recActive = false; recPaused = false;
    stopTimer(true);
    if (silent) {
      try { recorder.mediaRecorder && recorder.mediaRecorder.state !== 'inactive' && recorder.mediaRecorder.stop(); } catch (e) {}
      try { recorder.stream && recorder.stream.getTracks().forEach(function(t) { t.stop(); }); } catch (e) {}
      setUI('idle');
      return;
    }
    setUI('processing');
    updateStatus('Transcribing...', 'saving');

    recorder.stop().then(function(blob) {
      if (!blob || blob.size === 0) { updateStatus('Nothing recorded', 'err'); setUI('idle'); return; }
      if (typeof transcribeAudio !== 'function') { updateStatus('Transcription unavailable', 'err'); setUI('idle'); return; }
      return transcribeAudio(blob).then(function(resp) {
        if (!resp || !resp.success || !resp.text) {
          var msg = (resp && (resp.error || (resp.noProvider ? 'No STT provider configured' : null))) || 'Transcription failed';
          updateStatus(msg, 'err'); setUI('idle'); return;
        }
        updateStatus('Generating note...', 'saving');
        var modelEl = document.getElementById('notes-model-select');
        var selectedModel = modelEl ? modelEl.value : '';
        return options.noteFromVoice({ transcript: resp.text, model: selectedModel || undefined })
          .then(function(data) {
            setUI('idle');
            if (!data.success) { updateStatus(data.error || 'Generation failed', 'err'); return; }
            if (typeof options.applyGeneratedNote === 'function') options.applyGeneratedNote(data.title || 'Voice note', data.body || '');
            updateStatus('Generated - autosaving...', 'ok');
            if (typeof options.markDirty === 'function') options.markDirty();
            if (typeof options.scheduleAutosave === 'function') options.scheduleAutosave();
          });
      });
    }).catch(function(err) {
      setUI('idle');
      updateStatus(err.message || 'Recording failed', 'err');
    });
  }

  function isActive() {
    return recActive;
  }

  function startTimer() {
    var el = getEl('notes-rec-timer');
    if (recTimer || !el) return;
    recTimer = createTimerLite(el);
    recTimer.start();
  }

  function stopTimer(reset) {
    if (recTimer) recTimer.stop();
    if (reset && recTimer) { recTimer.reset(); recTimer = null; }
  }

  function createTimerLite(el) {
    var s = 0, iv = null;
    function paint() { el.textContent = String(Math.floor(s/60)).padStart(2,'0') + ':' + String(s%60).padStart(2,'0'); }
    return {
      start: function() { paint(); if (!iv) iv = setInterval(function() { s++; paint(); }, 1000); },
      stop:  function() { if (iv) { clearInterval(iv); iv = null; } },
      reset: function() { s = 0; paint(); }
    };
  }

  function setUI(state) {
    var startBtn = getEl('btn-note-rec-start');
    var pause = getEl('btn-note-rec-pause');
    var stopBtn = getEl('btn-note-rec-stop');
    var ind = getEl('notes-rec-indicator');
    var stateEl = getEl('notes-rec-state');
    var dot = ind ? ind.querySelector('.pulse-dot') : null;
    if (!startBtn) return;

    var idle = (state === 'idle');
    var recording = (state === 'recording');
    var paused = (state === 'paused');
    var processing = (state === 'processing');

    startBtn.classList.toggle('hidden', !idle);
    pause.classList.toggle('hidden', !(recording || paused));
    stopBtn.classList.toggle('hidden', !(recording || paused));
    ind.classList.toggle('hidden', idle);

    if (pause) pause.innerHTML = paused ? '<i class="fas fa-play"></i> Resume' : '<i class="fas fa-pause"></i> Pause';
    if (stateEl) stateEl.textContent = processing ? 'Processing...' : (paused ? 'Paused' : 'Recording');
    if (dot) dot.classList.toggle('paused', paused || processing);

    startBtn.disabled = !idle;
    pause.disabled = processing;
    stopBtn.disabled = processing;
  }

  function getEl(id) {
    if (typeof options.getEl === 'function') return options.getEl(id);
    return document.getElementById(id);
  }

  function updateStatus(text, kind) {
    if (typeof options.updateStatus === 'function') options.updateStatus(text, kind);
  }

  return {
    start: start,
    togglePause: togglePause,
    stop: stop,
    isActive: isActive,
    setUI: setUI
  };
}
