use crate::*;

/// Process MIDI events
pub fn process_events<F: ChunkFactory, const COLS: usize, const ROWS: usize>(
    process_handler: &mut ProcessHandler<F, COLS, ROWS>,
    ps: &jack::ProcessScope,
) -> Result<()> {
    // First, collect all MIDI events into a fixed-size array
    // This avoids allocations while solving borrow checker issues
    const MAX_EVENTS: usize = 16; // Reasonable limit for real-time processing
    let mut raw_events = [[0u8; 3]; MAX_EVENTS];
    let mut event_count = 0;

    // Collect events from the MIDI input iterator
    let midi_input = process_handler.ports().midi_in.iter(ps);
    for midi_event in midi_input {
        if event_count < MAX_EVENTS && midi_event.bytes.len() >= 3 {
            raw_events[event_count][0] = midi_event.bytes[0];
            raw_events[event_count][1] = midi_event.bytes[1];
            raw_events[event_count][2] = midi_event.bytes[2];
            event_count += 1;
        } else {
            return Err(LooperError::OutOfBounds(std::panic::Location::caller()));
        }
    }

    // Now process the collected events using wmidi
    // The iterator borrow is dropped, so we can mutably borrow process_handler
    for i in 0..event_count {
        let event_bytes = &raw_events[i];

        // Use wmidi for cleaner MIDI parsing instead of manual byte checking
        match wmidi::MidiMessage::try_from(&event_bytes[..]) {
            Ok(message) => {
                match message {
                    wmidi::MidiMessage::ControlChange(_, controller, value) => {
                        let controller_num = u8::from(controller);
                        let value_num = u8::from(value);

                        match controller_num {
                            // Expression Pedals
                            1 => {
                                process_handler.handle_pedal_a(value_num)?;
                            }
                            2 => {
                                process_handler.handle_pedal_b(value_num)?;
                            }
                            // Buttons
                            20 if value_num > 0 => {
                                process_handler.handle_button_1()?;
                            }
                            21 if value_num > 0 => {
                                process_handler.handle_button_2()?;
                            }
                            22 if value_num > 0 => {
                                process_handler.handle_button_3()?;
                            }
                            23 if value_num > 0 => {
                                process_handler.handle_button_4()?;
                            }
                            24 if value_num > 0 => {
                                process_handler.handle_button_5(ps)?;
                            }
                            25 if value_num > 0 => {
                                process_handler.handle_button_6()?;
                            }
                            26 if value_num > 0 => {
                                process_handler.handle_button_7()?;
                            }
                            27 if value_num > 0 => {
                                process_handler.handle_button_8()?;
                            }
                            28 if value_num > 0 => {
                                process_handler.handle_button_9()?;
                            }
                            29 if value_num > 0 => {
                                process_handler.handle_button_10()?;
                            }
                            30 if value_num > 0 => {
                                process_handler.handle_button_up()?;
                            }
                            31 if value_num > 0 => {
                                process_handler.handle_button_down()?;
                            }
                            // Other CC messages - ignore
                            _ => {}
                        }
                    }
                    // Other MIDI messages - ignore
                    _ => {}
                }
            }
            // Malformed MIDI messages - ignore
            Err(_) => {}
        }
    }

    Ok(())
}
