import Carbon
import Foundation

/// 管理输入法切换，用于在粘贴前临时切换到 ASCII 输入源
struct InputSourceManager {

    /// 获取当前输入源 ID
    static func currentInputSourceID() -> String? {
        guard let source = TISCopyCurrentKeyboardInputSource()?.takeRetainedValue() else {
            return nil
        }
        return TISGetInputSourceProperty(source, kTISPropertyInputSourceID)
            .flatMap { Unmanaged<CFString>.fromOpaque($0).takeUnretainedValue() as String }
    }

    /// 判断当前输入源是否为 CJK 输入法
    static func isCJKInputSource() -> Bool {
        guard let id = currentInputSourceID() else { return false }
        let cjkPrefixes = [
            "com.apple.inputmethod.Kotoeri",       // 日语
            "com.apple.inputmethod.SCIM",          // 简体中文
            "com.apple.inputmethod.TCIM",          // 繁体中文
            "com.apple.inputmethod.Korean",        // 韩语
            "com.apple.inputmethod.2SetHangul",
            "com.apple.inputmethod.3SetHangul",
            "com.apple.inputmethod.390Hangul",
            "com.apple.inputmethod.GongjinCheong",
            "com.apple.inputmethod.HNC"
        ]
        return cjkPrefixes.contains(where: { id.hasPrefix($0) })
    }

    /// 查找 ASCII 输入源（ABC 键盘）
    static func findASCIIInputSource() -> TISInputSource? {
        let properties: [CFString: Any] = [
            kTISPropertyInputSourceType: kTISTypeKeyboardLayout as CFString,
            kTISPropertyInputSourceIsASCIICapable: true as CFBoolean
        ]
        guard let list = TISCreateInputSourceList(properties as CFDictionary, false)?
            .takeRetainedValue() as? [TISInputSource] else {
            return nil
        }
        // 优先选择 "ABC" 或 "U.S."
        for source in list {
            if let id = TISGetInputSourceProperty(source, kTISPropertyInputSourceID)
                .flatMap({ Unmanaged<CFString>.fromOpaque($0).takeUnretainedValue() as String }) {
                if id == "com.apple.keylayout.ABC" || id == "com.apple.keylayout.US" {
                    return source
                }
            }
        }
        // 回退到第一个 ASCII 能力的输入源
        return list.first
    }

    /// 切换到指定输入源并返回原输入源
    static func switchToASCII() -> TISInputSource? {
        let original = TISCopyCurrentKeyboardInputSource()?.takeRetainedValue()
        guard let asciiSource = findASCIIInputSource() else {
            return original
        }
        TISSelectInputSource(asciiSource)
        return original
    }

    /// 恢复到指定输入源
    static func restore(_ source: TISInputSource?) {
        guard let source = source else { return }
        TISSelectInputSource(source)
    }
}
