use rdev::{Button, Key};

/// 判断键名是否为修饰键（Ctrl / Shift / Alt / Cmd），用于组合键检测。
pub fn is_modifier(name: &str) -> bool {
    matches!(
        name,
        "CtrlLeft"
            | "CtrlRight"
            | "ShiftLeft"
            | "ShiftRight"
            | "AltLeft"
            | "AltRight"
            | "CmdLeft"
            | "CmdRight"
    )
}

/// 将 rdev::Key 转换为可读短名，并把左右修饰键合并（如左右 Shift 统一为 "Shift"）。
pub fn format_key(key: &Key) -> String {
    match key {
        Key::KeyA => "A".into(),
        Key::KeyB => "B".into(),
        Key::KeyC => "C".into(),
        Key::KeyD => "D".into(),
        Key::KeyE => "E".into(),
        Key::KeyF => "F".into(),
        Key::KeyG => "G".into(),
        Key::KeyH => "H".into(),
        Key::KeyI => "I".into(),
        Key::KeyJ => "J".into(),
        Key::KeyK => "K".into(),
        Key::KeyL => "L".into(),
        Key::KeyM => "M".into(),
        Key::KeyN => "N".into(),
        Key::KeyO => "O".into(),
        Key::KeyP => "P".into(),
        Key::KeyQ => "Q".into(),
        Key::KeyR => "R".into(),
        Key::KeyS => "S".into(),
        Key::KeyT => "T".into(),
        Key::KeyU => "U".into(),
        Key::KeyV => "V".into(),
        Key::KeyW => "W".into(),
        Key::KeyX => "X".into(),
        Key::KeyY => "Y".into(),
        Key::KeyZ => "Z".into(),
        Key::Num0 => "0".into(),
        Key::Num1 => "1".into(),
        Key::Num2 => "2".into(),
        Key::Num3 => "3".into(),
        Key::Num4 => "4".into(),
        Key::Num5 => "5".into(),
        Key::Num6 => "6".into(),
        Key::Num7 => "7".into(),
        Key::Num8 => "8".into(),
        Key::Num9 => "9".into(),
        Key::F1 => "F1".into(),
        Key::F2 => "F2".into(),
        Key::F3 => "F3".into(),
        Key::F4 => "F4".into(),
        Key::F5 => "F5".into(),
        Key::F6 => "F6".into(),
        Key::F7 => "F7".into(),
        Key::F8 => "F8".into(),
        Key::F9 => "F9".into(),
        Key::F10 => "F10".into(),
        Key::F11 => "F11".into(),
        Key::F12 => "F12".into(),
        Key::Escape => "Esc".into(),
        Key::Space => "Space".into(),
        Key::ControlLeft => "CtrlLeft".into(),
        Key::ControlRight => "CtrlRight".into(),
        Key::ShiftLeft => "ShiftLeft".into(),
        Key::ShiftRight => "ShiftRight".into(),
        Key::Alt => "AltLeft".into(),
        Key::AltGr => "AltRight".into(),
        Key::MetaLeft => "CmdLeft".into(),
        Key::MetaRight => "CmdRight".into(),
        Key::Tab => "Tab".into(),
        Key::Return => "Enter".into(),
        Key::Backspace => "Backspace".into(),
        Key::Delete => "Delete".into(),
        Key::Home => "Home".into(),
        Key::End => "End".into(),
        Key::PageUp => "PageUp".into(),
        Key::PageDown => "PageDown".into(),
        Key::UpArrow => "↑".into(),
        Key::DownArrow => "↓".into(),
        Key::LeftArrow => "←".into(),
        Key::RightArrow => "→".into(),
        Key::Minus => "-".into(),
        Key::Equal => "=".into(),
        Key::LeftBracket => "[".into(),
        Key::RightBracket => "]".into(),
        Key::SemiColon => ";".into(),
        Key::Quote => "'".into(),
        Key::BackSlash => "\\".into(),
        Key::IntlBackslash => "\\".into(),
        Key::Comma => ",".into(),
        Key::Dot => ".".into(),
        Key::Slash => "/".into(),
        Key::BackQuote => "`".into(),
        Key::CapsLock => "CapsLock".into(),
        Key::Insert => "Insert".into(),
        Key::KpReturn => "KpEnter".into(),
        Key::KpMinus => "Kp-".into(),
        Key::KpPlus => "Kp+".into(),
        Key::KpMultiply => "Kp*".into(),
        Key::KpDivide => "Kp/".into(),
        Key::Kp0 => "Kp0".into(),
        Key::Kp1 => "Kp1".into(),
        Key::Kp2 => "Kp2".into(),
        Key::Kp3 => "Kp3".into(),
        Key::Kp4 => "Kp4".into(),
        Key::Kp5 => "Kp5".into(),
        Key::Kp6 => "Kp6".into(),
        Key::Kp7 => "Kp7".into(),
        Key::Kp8 => "Kp8".into(),
        Key::Kp9 => "Kp9".into(),
        Key::KpDelete => "KpDel".into(),
        Key::Function => "Fn".into(),
        Key::PrintScreen => "PrtSc".into(),
        Key::ScrollLock => "ScrLk".into(),
        Key::Pause => "Pause".into(),
        Key::NumLock => "NumLock".into(),
        // macOS 外接键盘特定键码（rdev 未映射）
        Key::Unknown(117) => "Delete".into(), // Forward Delete
        Key::Unknown(116) => "PageUp".into(), // Page Up
        Key::Unknown(121) => "PageDown".into(), // Page Down
        Key::Unknown(62) => "CtrlRight".into(), // Right Control
        // 未在显式列表中的键 fallback 到 Debug 字符串
        Key::Unknown(n) => format!("Unknown({})", n),
    }
}

/// 将 rdev::Button 转换为可读短名。
pub fn format_button(btn: &Button) -> String {
    match btn {
        Button::Left => "左键".into(),
        Button::Right => "右键".into(),
        Button::Middle => "中键".into(),
        Button::Unknown(n) => format!("未知({})", n),
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_is_modifier() {
        assert!(is_modifier("CtrlLeft"));
        assert!(is_modifier("CtrlRight"));
        assert!(is_modifier("ShiftLeft"));
        assert!(is_modifier("ShiftRight"));
        assert!(is_modifier("AltLeft"));
        assert!(is_modifier("AltRight"));
        assert!(is_modifier("CmdLeft"));
        assert!(is_modifier("CmdRight"));
        assert!(!is_modifier("Ctrl"));
        assert!(!is_modifier("Shift"));
        assert!(!is_modifier("A"));
        assert!(!is_modifier("Space"));
    }

    #[test]
    fn test_format_key_letters() {
        assert_eq!(format_key(&Key::KeyA), "A");
        assert_eq!(format_key(&Key::KeyZ), "Z");
    }

    #[test]
    fn test_format_key_modifiers_split() {
        assert_eq!(format_key(&Key::ShiftLeft), "ShiftLeft");
        assert_eq!(format_key(&Key::ShiftRight), "ShiftRight");
        assert_eq!(format_key(&Key::ControlLeft), "CtrlLeft");
        assert_eq!(format_key(&Key::ControlRight), "CtrlRight");
        assert_eq!(format_key(&Key::MetaLeft), "CmdLeft");
        assert_eq!(format_key(&Key::MetaRight), "CmdRight");
        assert_eq!(format_key(&Key::Alt), "AltLeft");
        assert_eq!(format_key(&Key::AltGr), "AltRight");
    }

    #[test]
    fn test_format_key_specials() {
        assert_eq!(format_key(&Key::Escape), "Esc");
        assert_eq!(format_key(&Key::Space), "Space");
        assert_eq!(format_key(&Key::Backspace), "Backspace");
        assert_eq!(format_key(&Key::Delete), "Delete");
        assert_eq!(format_key(&Key::Return), "Enter");
    }

    #[test]
    fn test_format_key_unknown() {
        assert_eq!(format_key(&Key::Unknown(999)), "Unknown(999)");
    }

    #[test]
    fn test_format_button() {
        assert_eq!(format_button(&Button::Left), "左键");
        assert_eq!(format_button(&Button::Right), "右键");
        assert_eq!(format_button(&Button::Middle), "中键");
        assert_eq!(format_button(&Button::Unknown(7)), "未知(7)");
    }
}
