const SonicMidiExtractor = (function() {
  const NOTE_NAMES = ['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'];

  function midiPitchToNoteName(pitch) {
    const note = NOTE_NAMES[pitch % 12];
    const octave = Math.floor(pitch / 12) - 1;
    return note + octave;
  }

  function extractSelectedMIDIContext(tracks, selectedItemId, bpm) {
    let targetItem = null;
    let targetTrack = null;

    for (const track of tracks) {
      const items = track.midiItems || [];
      const item = items.find(i => i.id === selectedItemId);
      if (item) { targetItem = item; targetTrack = track; break; }
    }

    if (!targetItem) {
      throw new Error('Please select a MIDI Item on the Timeline before requesting a Rearrangement!');
    }

    const notes = targetItem.notes || [];
    if (notes.length === 0) {
      throw new Error('Selected MIDI item has no notes to rearrange.');
    }

    const compactNotes = notes.map(n => ({
      pitch: n.pitch,
      note_name: midiPitchToNoteName(n.pitch),
      start_beat: parseFloat((n.start_beat || 0).toFixed(2)),
      duration_beats: parseFloat((n.duration_beats || 1).toFixed(2)),
      velocity: parseFloat((n.velocity || 0.8).toFixed(2))
    }));

    const totalDurationBeats = compactNotes.reduce((max, n) => Math.max(max, n.start_beat + n.duration_beats), 0);

    return {
      track_name: targetTrack.name,
      track_id: targetTrack.id,
      item_id: targetItem.id,
      item_name: targetItem.name,
      duration_bars: targetItem.length_bars || Math.ceil(totalDurationBeats / 4),
      total_beats: Math.ceil(totalDurationBeats),
      bpm: parseInt(bpm || '120'),
      total_notes: compactNotes.length,
      notes: compactNotes,
      instrument: targetTrack.synth_engine ? {
        soundfont_id: targetTrack.synth_engine.soundfont_id || '',
        soundfont_bank: targetTrack.synth_engine.soundfont_bank ?? 0,
        soundfont_program: targetTrack.synth_engine.soundfont_program ?? 0
      } : null
    };
  }

  return { extractSelectedMIDIContext, midiPitchToNoteName };
})();

window.SonicMidiExtractor = SonicMidiExtractor;
