//
//  KMBaseTextField.swift
//  PDF Master
//
//  Created by lizhe on 2022/12/12.
//

import Cocoa

typealias KMBaseTextFieldTextDidEndEditing = (_ string: String) -> Void
typealias KMBaseTextFieldTextTextDidChange = (_ string: String) -> Void
typealias KMBaseTextFieldTextTextDidBeginEditing = (_ string: String) -> Void
typealias KMBaseTextFieldTextTextDeleteAction = (_ string: String) -> Void

class KMBaseTextField: NSView {
    var textDidEndEditing: KMBaseTextFieldTextDidEndEditing?
    var textDidChange: KMBaseTextFieldTextTextDidChange?
    var textDidBeginEditing: KMBaseTextFieldTextTextDidBeginEditing?
    var textDeleteAction: KMBaseTextFieldTextTextDeleteAction?
    
    var presenter: KMBaseTextFieldPresenter = KMBaseTextFieldPresenter()
    var model: KMBaseTextFieldModel = KMBaseTextFieldModel() {
        didSet {
            self.textFormatter.model = model
        }
    }
    lazy var textField: FocusAwareTextField = FocusAwareTextField()
    var stringValue: String {
        set {
            textField.stringValue = newValue + self.model.specialChart
            self.model.value = stringValue
        }
        get {
            self.model.value
        }
    }
    var placeholderString: String? {
        didSet {
            self.textField.placeholderString = placeholderString!
            self.model.placeholderString = placeholderString!
        }
    }
    var isEnabled: Bool? {
        didSet {
            self.textField.isEnabled = isEnabled!
            self.model.isEnabled = isEnabled!
        }
    }
    var minLen: Int? {
        didSet {
            self.model.minLen = minLen!
        }
    }
    var maxLen: Int = 999 {
        didSet {
            self.model.maxLen = maxLen
        }
    }
    var minValue: Int? {
        didSet {
            self.model.minValue = minValue!
        }
    }
    var maxValue: Int? {
        didSet {
            self.model.maxValue = maxValue!
        }
    }

    var onlyNumber: Bool? {
        didSet {
            self.model.onlyNumber = onlyNumber!
            if onlyNumber! {
                self.textField.formatter = self.textFormatter
            } else {
                self.textField.formatter = nil
            }
        }
    }

    var inputType: KMBaseTextFieldInputType? {
        didSet {
            if (inputType == .int) {
                self.model.specialChart = "-"
            } else if (inputType == .float) {
                self.model.specialChart = ".-"
            } else if (inputType == .percent) {
                self.model.specialChart = "%"
            }
        }
    }
    var textFormatter: KMBaseTextFormatter = KMBaseTextFormatter()
    
    override func awakeFromNib() {
        self.addSubview(self.textField)
        self.textField.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            self.textField.topAnchor.constraint(equalTo: topAnchor),
            self.textField.leftAnchor.constraint(equalTo: leftAnchor),
            self.textField.rightAnchor.constraint(equalTo: rightAnchor),
            self.textField.bottomAnchor.constraint(equalTo: bottomAnchor)])
        self.textField.updateConstraintsForSubtreeIfNeeded()
        self.textField.formatter = self.textFormatter
        self.textField.wantsLayer = true
        self.textField.layer?.borderWidth = 0
        self.textField.layer?.borderColor = NSColor.clear.cgColor
        self.textField.drawsBackground = false
        self.textField.layer?.backgroundColor = NSColor.clear.cgColor
        self.textField.backgroundColor = NSColor.clear
        self.textField.isBordered = false
//        self.textField.font = FONT_R(13.);
//        self.textField.textColor = [[NSColor whiteColor] colorWithAlphaComponent:0.87];
        
        self.textField.delegate = self
        self.textFormatter.model = self.model
        self.presenter.initPresenter(delegate: self, model: self.model)
    }
}

extension KMBaseTextField: NSTextFieldDelegate {
    func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
        switch commandSelector {
        case #selector(NSResponder.insertNewline(_:)):
            if let inputView = control as? NSTextField {
                //当当前TextField按下enter
                if inputView == textField {
                    KMPrint("按下 enter")
                    if self.textDidEndEditing != nil {
                        self.textDidEndEditing!(self.model.stringValue)
                    }
                }
            }
            return true
        case #selector(NSResponder.deleteBackward(_:)):
            if let inputView = control as? NSTextField {
                //当当前TextField按下enter
                if inputView == textField {
                    KMPrint("按下 delete")
                    if inputView.stringValue == "" {
                        if self.textDeleteAction != nil {
                            self.textDeleteAction!(self.model.stringValue)
                        }
                        return true
                    }
                    
                }
            }
            return false
        default:
            return false
        }
    }
                
    func controlTextDidChange(_ obj: Notification) {
        KMPrint("controlTextDidChange")
        if self.textField.stringValue.count >= self.maxLen {
            var string = self.textField.stringValue
            string = String(string.prefix(1))
            self.textField.stringValue = string
        }
        self.presenter.changeValue(value: self.textField.stringValue)
        if self.textDidChange != nil {
            self.textDidChange!(self.model.stringValue)
        }
    }
    
    func controlTextDidEndEditing(_ obj: Notification) {
        KMPrint("controlTextDidEndEditing")
        self.presenter.changeValue(value: self.textField.stringValue)
        
        if self.textDidEndEditing != nil {
            self.textDidEndEditing!(self.model.stringValue)
        }
    }
    
    func controlTextDidBeginEditing(_ obj: Notification) {
        KMPrint("controlTextDidBeginEditing")
        if self.textDidBeginEditing != nil {
            self.textDidBeginEditing!(self.model.stringValue)
        }
    }
    
    func control(_ control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool {
        KMPrint("textShouldEndEditing")
        return true
    }
}

extension KMBaseTextField: KMBaseTextFieldPresenterDelegate {
    func valueDidChange(presenter: KMBaseTextFieldPresenter, model: KMBaseTextFieldModel) {
        self.model = model
        self.textField.stringValue = model.stringValue
    }
}

//extension NSTextField {
//    open override func becomeFirstResponder() -> Bool {
//        let success = super.becomeFirstResponder()
//        if success {
//            let textView: NSTextView = self.currentEditor() as! NSTextView
//            if textView?.responds(to: #selector(insetionpoint)) {
//                let color = self.textColor
//                textView.setInsertionPointColor(color)
//            }
//        }
//        return success
//    }
//}

//extension NSTextField {
////    var onFocus: () -> Void = {}
////    var onUnfocus: () -> Void = {}
//
//    open override func becomeFirstResponder() -> Bool {
////        onFocus()
//        let textView = window?.fieldEditor(true, for: nil) as? NSTextView
//        textView?.insertionPointColor = NSColor.red
//        return super.becomeFirstResponder()
//    }
//
//    open override func resignFirstResponder() -> Bool {
////        onUnfocus()
//        return super.resignFirstResponder()
//    }
//}

class FocusAwareTextField: NSTextField, NSTextFieldDelegate {
    var onFocus: () -> Void = {}
    var onUnfocus: () -> Void = {}

    override func becomeFirstResponder() -> Bool {
        onFocus()
        let textView = window?.fieldEditor(true, for: nil) as? NSTextView
        textView?.insertionPointColor = NSColor.km_init(hex: "#252629")
        return super.becomeFirstResponder()
    }

//    override func resignFirstResponder() -> Bool {
//        onUnfocus()
//        return super.resignFirstResponder()
//    }
    
    func controlTextDidEndEditing(_ obj: Notification) {
        let textField = obj.object as? NSTextField
        if (textField == self) {
            onUnfocus()
        }
    }
}