use defmt::info;
use embedded_midi::{MidiIn, MidiMessage, Channel, Control};
use crate::led_state::LedState;
use stm32f0xx_hal as hal;

pub struct MidiProcessor;

impl MidiProcessor {
    pub fn process_message(
        midi_rx: &mut MidiIn<hal::serial::Rx<hal::stm32::USART1>>,
        led_state: &mut LedState,
    ) {
        match midi_rx.read() {
            Ok(MidiMessage::ControlChange(channel, control, value))
                if channel == Channel::C1 =>
            {
                Self::handle_control_change(control, value, led_state);
            }
            Ok(_) => {
                info!("unhandled midi message");
            }
            Err(nb::Error::WouldBlock) => {}
            Err(nb::Error::Other(hal::serial::Error::Framing)) => {
                info!("Error::Framing");
            }
            Err(nb::Error::Other(hal::serial::Error::Noise)) => {
                info!("Error::Noise");
            }
            Err(nb::Error::Other(hal::serial::Error::Overrun)) => {
                info!("Error::Overrun");
            }
            Err(nb::Error::Other(hal::serial::Error::Parity)) => {
                info!("Error::Parity");
            }
            Err(nb::Error::Other(_)) => {
                info!("Error::Other");
            }
        }
    }

    fn handle_control_change(control: Control, value: midi_types::Value7, led_state: &mut LedState) {
        let value: u8 = value.into();
        
        match control.into() {
            31 => {
                led_state.switch_1 = value & 0b0000_0001 != 0;
                led_state.switch_2 = value & 0b0000_0010 != 0;
                led_state.expression_1 = value & 0b0000_0100 != 0;
                led_state.expression_2 = value & 0b0000_1000 != 0;
            }
            32 => {
                led_state.switches = value & 0b0000_0001 != 0;
                led_state.select = value & 0b0000_0010 != 0;
                led_state.number = value & 0b0000_0100 != 0;
                led_state.value_1 = value & 0b0000_1000 != 0;
                led_state.value_2 = value & 0b0001_0000 != 0;
            }
            33 => {
                led_state.direct_select = value & 0b0000_0001 != 0;
                led_state.midi_function = value & 0b0000_0010 != 0;
                led_state.midi_chan = value & 0b0000_0100 != 0;
                led_state.config = value & 0b0000_1000 != 0;
            }
            34 => {
                led_state.digit_0.a = value & 0b0000_0001 != 0;
                led_state.digit_0.b = value & 0b0000_0010 != 0;
                led_state.digit_0.c = value & 0b0000_0100 != 0;
                led_state.digit_0.d = value & 0b0000_1000 != 0;
                led_state.digit_0.e = value & 0b0001_0000 != 0;
                led_state.digit_0.f = value & 0b0010_0000 != 0;
                led_state.digit_0.g = value & 0b0100_0000 != 0;
            }
            35 => {
                led_state.digit_1.a = value & 0b0000_0001 != 0;
                led_state.digit_1.b = value & 0b0000_0010 != 0;
                led_state.digit_1.c = value & 0b0000_0100 != 0;
                led_state.digit_1.d = value & 0b0000_1000 != 0;
                led_state.digit_1.e = value & 0b0001_0000 != 0;
                led_state.digit_1.f = value & 0b0010_0000 != 0;
                led_state.digit_1.g = value & 0b0100_0000 != 0;
            }
            36 => {
                led_state.digit_2.a = value & 0b0000_0001 != 0;
                led_state.digit_2.b = value & 0b0000_0010 != 0;
                led_state.digit_2.c = value & 0b0000_0100 != 0;
                led_state.digit_2.d = value & 0b0000_1000 != 0;
                led_state.digit_2.e = value & 0b0001_0000 != 0;
                led_state.digit_2.f = value & 0b0010_0000 != 0;
                led_state.digit_2.g = value & 0b0100_0000 != 0;
            }
            37 => {
                led_state.buttons[0] = value & 0b0000_0001 != 0;
                led_state.buttons[1] = value & 0b0000_0010 != 0;
                led_state.buttons[2] = value & 0b0000_0100 != 0;
                led_state.buttons[3] = value & 0b0000_1000 != 0;
                led_state.buttons[4] = value & 0b0001_0000 != 0;
            }
            38 => {
                led_state.buttons[0] = value & 0b0000_0001 != 0;
                led_state.buttons[1] = value & 0b0000_0010 != 0;
                led_state.buttons[2] = value & 0b0000_0100 != 0;
                led_state.buttons[3] = value & 0b0000_1000 != 0;
                led_state.buttons[4] = value & 0b0001_0000 != 0;
            }
            _ => {}
        }
    }
}