"""Converters — transform generator output to MIDI notes for SongDefinition.

rhythm generators → MidiNote list (channel → GM pitch mapping)
melodic generators → MidiNote list (note["key"] = pitch directly)
"""

from __future__ import annotations

from src.core.schema import MidiNote

# ---------------------------------------------------------------------------
# GM drum pitch mapping — channels 10-16
# ---------------------------------------------------------------------------
CHANNEL_PITCH: dict[int, int] = {
    10: 39,   # perc  (General MIDI channel 10 = percussion)
    11: 36,   # kick
    12: 38,   # snare
    13: 37,   # rim
    14: 50,   # perc2
    15: 42,   # hihat
    16: 39,   # clap
}


def rhythm_to_midi(note_dict: dict[int, list[dict]]) -> list[MidiNote]:
    """Convert rhythm generator output (channel → note list) to MidiNote list.

    note_dict: {channel: [{"pos", "len", "key", "vel"}, ...]}
    - channel must be in CHANNEL_PITCH (10-16)
    - pitch = CHANNEL_PITCH[channel]
    - start = note["pos"]
    - duration = note["len"]
    - velocity = note["vel"]
    """
    midi_notes: list[MidiNote] = []
    for channel, notes in note_dict.items():
        pitch = CHANNEL_PITCH.get(channel, 60)
        for note in notes:
            midi_notes.append(MidiNote(
                pitch=pitch,
                start=note["pos"],
                duration=note["len"],
                velocity=note["vel"],
            ))
    return midi_notes


def melodic_to_midi(note_list: list[dict]) -> list[MidiNote]:
    """Convert melodic generator output (list of note dicts) to MidiNote list.

    note_list: [{"pos", "len", "key", "vel"}, ...]
    - pitch = note["key"]  (directly used, not mapped)
    - start = note["pos"]
    - duration = note["len"]
    - velocity = note["vel"]
    """
    return [
        MidiNote(
            pitch=note["key"],
            start=note["pos"],
            duration=note["len"],
            velocity=note["vel"],
        )
        for note in note_list
    ]