use libcolors::{
    event::{KeyInput, KeyModifiers},
    input::Key,
};
// use yggdrasil_abi::io::{KeyboardKey, KeyboardKeyEvent};

#[derive(Default)]
pub struct InputState {
    lshift: bool,
    rshift: bool,
    lctrl: bool,
    rctrl: bool,
    lalt: bool,
    ralt: bool,
}

impl InputState {
    pub fn update(&mut self, key: Key, state: bool) {
        match key {
            Key::LAlt => self.lalt = state,
            Key::RAlt => self.ralt = state,
            Key::LShift => self.lshift = state,
            Key::RShift => self.rshift = state,
            Key::LControl => self.lctrl = state,
            Key::RControl => self.rctrl = state,
            _ => (),
        }
    }

    fn translate_shift(ch: u8) -> u8 {
        static DIGIT_TRANS: &[u8] = b")!@#$%^&*(";

        match ch {
            ch if ch.is_ascii_lowercase() => ch.to_ascii_uppercase(),
            b'0'..=b'9' => DIGIT_TRANS[(ch - b'0') as usize],
            b';' => b':',
            b'\'' => b'"',
            b'/' => b'?',
            b'-' => b'_',
            b'=' => b'+',
            b',' => b'<',
            b'.' => b'>',
            b'`' => b'~',
            b'\\' => b'|',
            b'[' => b'{',
            b']' => b'}',
            _ => ch,
        }
    }

    pub fn make_input(&self, key: Key) -> KeyInput {
        let modifiers = self.modifiers();

        let input = match (key, modifiers) {
            (Key::Char(ch), KeyModifiers::NONE) => Some(ch as _),
            // TODO proper shift key translation
            (Key::Char(ch), KeyModifiers::SHIFT) => Some(Self::translate_shift(ch) as _),
            // (KeyboardKey::Tab, KeyModifiers::NONE) => Some('\t'),
            (Key::Enter, KeyModifiers::NONE) => Some('\n'),
            (_, _) => None,
        };

        KeyInput {
            modifiers,
            key,
            input,
        }
    }

    pub fn modifiers(&self) -> KeyModifiers {
        KeyModifiers {
            shift: self.lshift || self.rshift,
            ctrl: self.lctrl || self.rctrl,
            alt: self.lalt || self.ralt,
        }
    }
}

// impl FdEventSource<ServerEvent> for KeyboardInput {
//     fn poll_fd(&self) -> RawFd {
//         self.0.as_raw_fd()
//     }
//
//     fn read_event(&mut self) -> ServerEvent {
//     }
// }
