#if canImport(UIKit)
import UIKit

enum KeyMapping {
    /// X11 keysym values for special keys.
    enum X11 {
        static let backspace: UInt32 = 0xFF08
        static let tab: UInt32 = 0xFF09
        static let `return`: UInt32 = 0xFF0D
        static let escape: UInt32 = 0xFF1B
        static let delete: UInt32 = 0xFFFF

        static let home: UInt32 = 0xFF50
        static let leftArrow: UInt32 = 0xFF51
        static let upArrow: UInt32 = 0xFF52
        static let rightArrow: UInt32 = 0xFF53
        static let downArrow: UInt32 = 0xFF54
        static let pageUp: UInt32 = 0xFF55
        static let pageDown: UInt32 = 0xFF56
        static let end: UInt32 = 0xFF57
        static let insert: UInt32 = 0xFF63

        static let f1: UInt32 = 0xFFBE
        static let f2: UInt32 = 0xFFBF
        static let f3: UInt32 = 0xFFC0
        static let f4: UInt32 = 0xFFC1
        static let f5: UInt32 = 0xFFC2
        static let f6: UInt32 = 0xFFC3
        static let f7: UInt32 = 0xFFC4
        static let f8: UInt32 = 0xFFC5
        static let f9: UInt32 = 0xFFC6
        static let f10: UInt32 = 0xFFC7
        static let f11: UInt32 = 0xFFC8
        static let f12: UInt32 = 0xFFC9

        static let leftShift: UInt32 = 0xFFE1
        static let rightShift: UInt32 = 0xFFE2
        static let leftControl: UInt32 = 0xFFE3
        static let rightControl: UInt32 = 0xFFE4
        static let capsLock: UInt32 = 0xFFE5
        static let leftAlt: UInt32 = 0xFFE9
        static let rightAlt: UInt32 = 0xFFEA
        static let leftMeta: UInt32 = 0xFFE7
        static let rightMeta: UInt32 = 0xFFE8
        static let leftCommand: UInt32 = 0xFFEB
        static let rightCommand: UInt32 = 0xFFEC

        static let space: UInt32 = 0x0020
    }

    /// Convert a UIKey into one or more VNC keysyms (UInt32 X11 values).
    /// Returns nil if no mapping is found.
    static func keysym(for key: UIKey) -> UInt32? {
        let usage = key.keyCode
        if let mapped = mapHIDUsage(usage) {
            return mapped
        }
        let chars = key.charactersIgnoringModifiers
        guard let scalar = chars.unicodeScalars.first else { return nil }
        return scalar.value
    }

    static func modifierKeysyms(for flags: UIKeyModifierFlags) -> [UInt32] {
        var out: [UInt32] = []
        if flags.contains(.shift) { out.append(X11.leftShift) }
        if flags.contains(.control) { out.append(X11.leftControl) }
        if flags.contains(.alternate) { out.append(X11.leftAlt) }
        if flags.contains(.command) { out.append(X11.leftCommand) }
        return out
    }

    private static func mapHIDUsage(_ usage: UIKeyboardHIDUsage) -> UInt32? {
        switch usage {
        case .keyboardReturnOrEnter, .keypadEnter: return X11.return
        case .keyboardEscape: return X11.escape
        case .keyboardDeleteOrBackspace: return X11.backspace
        case .keyboardTab: return X11.tab
        case .keyboardSpacebar: return X11.space
        case .keyboardLeftArrow: return X11.leftArrow
        case .keyboardRightArrow: return X11.rightArrow
        case .keyboardUpArrow: return X11.upArrow
        case .keyboardDownArrow: return X11.downArrow
        case .keyboardHome: return X11.home
        case .keyboardEnd: return X11.end
        case .keyboardPageUp: return X11.pageUp
        case .keyboardPageDown: return X11.pageDown
        case .keyboardInsert: return X11.insert
        case .keyboardDeleteForward: return X11.delete
        case .keyboardCapsLock: return X11.capsLock
        case .keyboardLeftShift: return X11.leftShift
        case .keyboardRightShift: return X11.rightShift
        case .keyboardLeftControl: return X11.leftControl
        case .keyboardRightControl: return X11.rightControl
        case .keyboardLeftAlt: return X11.leftAlt
        case .keyboardRightAlt: return X11.rightAlt
        case .keyboardLeftGUI: return X11.leftCommand
        case .keyboardRightGUI: return X11.rightCommand
        case .keyboardF1: return X11.f1
        case .keyboardF2: return X11.f2
        case .keyboardF3: return X11.f3
        case .keyboardF4: return X11.f4
        case .keyboardF5: return X11.f5
        case .keyboardF6: return X11.f6
        case .keyboardF7: return X11.f7
        case .keyboardF8: return X11.f8
        case .keyboardF9: return X11.f9
        case .keyboardF10: return X11.f10
        case .keyboardF11: return X11.f11
        case .keyboardF12: return X11.f12
        default: return nil
        }
    }
}
#endif
