// src/logic/uart_cmd.rs

use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Channel;

// UART HW init
use crate::config::{PIPE_HW_TX, PIPE_HW_RX};
use crate::sleep::StopEntry;

pub static CMD_CH: Channel<CriticalSectionRawMutex, LowPowerCmd, 1> = Channel::new();

#[derive(Debug, Clone, Copy, PartialEq, Eq, defmt::Format)]
pub enum LowPowerCmd {
    Standby8k,     // 1
    StandbyFull,   // 2
    Standby,       // 3
    Shutdown,      // 4
    StopMode(StopModeConfig),
    Sleep,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, defmt::Format)]
pub struct StopModeConfig {
    pub mode: StopMode,
    pub entry: StopEntry,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, defmt::Format)]
pub enum StopMode {
    Stop0,
    Stop1,
    Stop2,
    Stop3,
}

#[embassy_executor::task]
pub async fn uart_cmd_task() {
    async fn print_menu() {
        while PIPE_HW_TX.len() > 0 {
            embassy_time::Timer::after(embassy_time::Duration::from_millis(8)).await;
        }
        let _ = PIPE_HW_TX.write(
            b"\x1B[2J\x1B[H\r\n\
            Modes:\r\n\
            [1] Standby + 8 KB SRAM2 retention\r\n\
            [2] Standby + full SRAM2 retention\r\n\
            [3] Standby minimal\r\n\
            [4] Shutdown\r\n\
            [5] Stop mode (0-3)\r\n\
            [6] Sleep mode (WFI or WFE)\r\n\
            "
        ).await;
        embassy_time::Timer::after(embassy_time::Duration::from_millis(8)).await;
    }

    print_menu().await;

    let mut b = [0u8; 2];
    loop {
        b.fill(0);
        let n = PIPE_HW_RX.read(&mut b).await;
        if n == 0 { continue; }

        match b[0] {
            b'1' => CMD_CH.send(LowPowerCmd::Standby8k).await,
            b'2' => CMD_CH.send(LowPowerCmd::StandbyFull).await,
            b'3' => CMD_CH.send(LowPowerCmd::Standby).await,
            b'4' => CMD_CH.send(LowPowerCmd::Shutdown).await,
            b'5' => {
                let _ = PIPE_HW_TX.write(b"Enter Stop mode number (0-3): ").await;
                b.fill(0);
                let n = PIPE_HW_RX.read(&mut b).await;
                if n == 0 { print_menu().await; continue; }
                let stop_mode = match b[0] {
                    b'0' => StopMode::Stop0,
                    b'1' => StopMode::Stop1,
                    b'2' => StopMode::Stop2,
                    b'3' => StopMode::Stop3,
                    _ => { print_menu().await; continue; }
                };

                if matches!(stop_mode, StopMode::Stop0) {
                    CMD_CH.send(LowPowerCmd::StopMode(StopModeConfig {
                        mode: stop_mode,
                        entry: StopEntry::Wfi, // to tu je, lebo nejdem prepisovat kod, kvoli
                                               // pos**temu halu co si nevie urobit konzistentnost
                    })).await;
                    continue;
                }
                let _ = PIPE_HW_TX.write(b"Enter entry method (1=WFI,2=WFE,3=WFE no clear): ").await;
                b.fill(0);
                let n = PIPE_HW_RX.read(&mut b).await;
                if n == 0 { print_menu().await; continue; }
                let entry = match b[0] {
                    b'1' => StopEntry::Wfi,
                    b'2' => StopEntry::Wfe,
                    b'3' => StopEntry::WfeNoEventClear,
                    _ => { print_menu().await; continue; }
                };
                CMD_CH.send(LowPowerCmd::StopMode(StopModeConfig { mode: stop_mode, entry })).await;
            },
            b'6' => CMD_CH.send(LowPowerCmd::Sleep).await,
            _ => { print_menu().await; continue; }
        }
    }
}
