//
//  SpeakKeyboardManager.swift
//  SpeakEasyLearnEnglish
//
//  Created by edy on 2025/7/11.
//

import UIKit


fileprivate var keyboardKey = SpeakEasyAssociatedKeys.windowkeyboardKey.rawValue

class SpeakKeyboardManager: NSObject {
    
    static let share = SpeakKeyboardManager()
    
    func monitor() -> Void {
        // 监听键盘事件
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardWillShow(_:)),
            name: UIResponder.keyboardWillShowNotification,
            object: nil
        )
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(keyboardWillHide(_:)),
            name: UIResponder.keyboardWillHideNotification,
            object: nil
        )
    }
    
    // MARK: - 键盘处理
    @objc private func keyboardWillShow(_ notification: Notification) {
        
        guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
        let currentFirstResponder = findFirstResponder(in: SpWindow)
        let keyboardTop = SpWindow.convert(keyboardFrame, from: nil).minY
        
        var textviewbottom:CGFloat = 0
        if let input = currentFirstResponder as? UITextField {
            textviewbottom = SpWindow.convert(input.bounds, from: input.superview).maxY
        }else if let input = currentFirstResponder as? UITextView {
            textviewbottom = SpWindow.convert(input.bounds, from: input.superview).maxY
        }
        SpWindow.iskeyboradShow = true
        if textviewbottom > keyboardTop {
            let overlap = (textviewbottom - keyboardTop) + (SpWindow.safeAreaInsets.bottom > 0 ? SpWindow.safeAreaInsets.bottom : 20)
            if overlap > 0 {
                var frame = SpWindow.frame
                frame.origin.y -= overlap
                SpWindow.frame = frame
            }
        }
    }
    
    @objc private func keyboardWillHide(_ notification: Notification) {
        SpWindow.iskeyboradShow = false
        SpWindow.frame = UIScreen.main.bounds
    }
    
    
    private override init() {
        
    }
    
    private func findFirstResponder(in view: UIView?) -> UIResponder? {
        guard let view = view else { return nil }
        if view.isFirstResponder {
            return view
        }
        for subview in view.subviews {
            if let firstResponder = findFirstResponder(in: subview) {
                return firstResponder
            }
        }
        return nil
    }
}



extension UIWindow {
    
    var iskeyboradShow:Bool {
        set {
            objc_setAssociatedObject(self, &keyboardKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        get {
            return objc_getAssociatedObject(self, &keyboardKey) as? Bool ?? false
        }
    }
    
    open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        guard self.point(inside: point, with: event) else {
            return nil
        }
        let frame = self.frame
        let view = super.hitTest(point, with: event)
        if view is UIButton {
            return view
        }else if (frame.origin.y < 0 || iskeyboradShow) && !(view is UITextField || view is UITextView) {
            self.endEditing(false)
            return nil
        }else{
            return view
        }
    }
    
}
