//
//  KMNBotaSearchTopVIew.swift
//  PDF Reader Pro
//
//  Created by User-Tangchao on 2024/12/1.
//

import Cocoa
import KMComponentLibrary

enum KMNBotaSearchTopItemKey: Int {
    case search = 1
    case replace = 2
    case `switch` = 3
    case previous = 4
    case next = 5
    case replaceText
    case replaceAllText
}

typealias KMNBotaSearchTopViewEnterAction = (_ string: String) -> Void
class KMNBotaSearchTopView: NSView, NibLoadable {
    @IBOutlet weak var topBox: NSBox!
    @IBOutlet weak var centerBox: NSBox!
    @IBOutlet weak var bottomBox: NSBox!
    
    @IBOutlet weak var centerHeightConst: NSLayoutConstraint!
    
    var itemClick: KMCommonClickBlock?
    var valueDidChange: KMValueDidChangeBlock?
    var replaceValueDidChange: KMValueDidChangeBlock?
    var enterAction: KMNBotaSearchTopViewEnterAction?
    
    private var topHeight_: CGFloat = 40
    private var centerHeight_ : CGFloat = 72
    private var bottomHeight_: CGFloat = 32
    private var vSpace_: CGFloat = 8
    
    private lazy var searchButton_: ComponentButton = {
        let view = ComponentButton()
        view.properties = ComponentButtonProperty(type: .text_gray, size: .xxxs, state: .normal, onlyIcon: true, icon: NSImage(named: "KMImageNameBotaSearch"))
        view.setTarget(self, action: #selector(searchAction))
        return view
    }()
    
    private lazy var searchInput_: NSTextField = {
        let view = NSTextField()
        view.placeholderString = KMLocalizedString("Search") + " (⌥⌘F)"
        view.isBordered = false
        view.drawsBackground = false
        view.delegate = self
        return view
    }()
    
    private lazy var replaceButton_: ComponentButton = {
        let view = ComponentButton()
        view.properties = ComponentButtonProperty(type: .text_gray_low, size: .xxs, state: .normal, onlyIcon: true, icon: NSImage(named: "KMImageNameBotaSearchReplace"), keepPressState: false)
        view.setTarget(self, action: #selector(replaceAction))
        return view
    }()
    
    private lazy var switchButton_: ComponentButton = {
        let view = ComponentButton()
        view.properties = ComponentButtonProperty(type: .text_gray_low, size: .xxs, state: .normal, onlyIcon: true, icon: NSImage(named: "KMImageNameBotaSearchSwitch"), keepPressState: false)
        view.setTarget(self, action: #selector(switchAction))
        return view
    }()
    
    private lazy var centerView_: KMNSearchReplaceItemView = {
        let view = KMNSearchReplaceItemView()
        return view
    }()
    
    private lazy var resultLabel_: NSTextField = {
        let view = NSTextField(labelWithString: "")
        view.font = ComponentLibrary.shared.getFontFromKey("mac/body-xs-medium")
        return view
    }()
    
    private lazy var previousButton_: ComponentButton = {
        let view = ComponentButton()
        view.properties = ComponentButtonProperty(type: .text_gray_low, size: .xxxs, state: .normal, onlyIcon: true, icon: NSImage(named: "KMImageNameBotaSearchPreviousDisable"), keepPressState: false)
        view.setTarget(self, action: #selector(previousAction))
        return view
    }()
    
    private lazy var nextButton_: ComponentButton = {
        let view = ComponentButton()
        view.properties = ComponentButtonProperty(type: .text_gray_low, size: .xxxs, state: .normal, onlyIcon: true, icon: NSImage(named: "KMImageNameBotaSearchNext"), keepPressState: false)
        view.setTarget(self, action: #selector(nextActon))
        return view
    }()
    
    private lazy var bottomLine_: NSView = {
        let view = NSView()
        view.wantsLayer = true
        return view
    }()
    
    var searchInput: NSTextField {
        get {
            return searchInput_
        }
    }
    
    var replaceInput: ComponentInput {
        get {
            return centerView_.input
        }
    }
    
    var replaceButton: ComponentButton {
        get {
            return centerView_.replaceButton
        }
    }
    
    var replaceAllButton: ComponentButton {
        get {
            return centerView_.replaceAllButton
        }
    }
    
    var previousButton: ComponentButton {
        get {
            return previousButton_
        }
    }
    
    var nextButton: ComponentButton {
        get {
            return nextButton_
        }
    }
    
    var resultLabel: NSTextField {
        get {
            return resultLabel_
        }
    }
    
    var bottomLine: NSView {
        get {
            return bottomLine_
        }
    }
    
    var inputValue: String? {
        get {
            return searchInput_.stringValue
        }
        set {
            searchInput_.stringValue = newValue ?? ""
        }
    }
    
    var replaceText: String? {
        get {
            return centerView_.inputValue
        }
        set {
            centerView_.inputValue = newValue ?? ""
        }
    }
    
    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // Drawing code here.
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        
        initSubviews()
    }
    
    func initSubviews() {
        topBox.borderWidth = 0
        topBox.contentView?.addSubview(searchButton_)
        searchButton_.km_add_leading_constraint(constant: 12)
        searchButton_.km_add_size_constraint(size: NSSize(width: 16, height: 16))
        searchButton_.km_add_centerY_constraint()
        
        topBox.contentView?.addSubview(searchInput_)
        searchInput_.km_add_leading_constraint(equalTo: searchButton_, attribute: .trailing, constant: 8)
        searchInput_.km_add_centerY_constraint()
        searchInput_.km_add_height_constraint(constant: 20)
        searchInput_.km_add_trailing_constraint(constant: -76)
        
        topBox.contentView?.addSubview(switchButton_)
        switchButton_.km_add_trailing_constraint(constant: -12)
        switchButton_.km_add_centerY_constraint()
        switchButton_.km_add_size_constraint(size: NSSize(width: 24, height: 24))
        
        topBox.contentView?.addSubview(replaceButton_)
        replaceButton_.km_add_trailing_constraint(equalTo: switchButton_, attribute: .leading, constant: -8)
        replaceButton_.km_add_centerY_constraint()
        replaceButton_.km_add_size_constraint(size: NSSize(width: 24, height: 24))
        
        topBox.contentView?.addSubview(bottomLine_)
        bottomLine.km_add_leading_constraint()
        bottomLine.km_add_trailing_constraint()
        bottomLine.km_add_height_constraint(constant: 2)
        bottomLine.km_add_bottom_constraint()
        
        centerBox.isHidden = true
        centerBox.borderWidth = 0
        centerBox.contentView = centerView_
        centerView_.itemClick = { [unowned self] idx, _ in
            if idx == 1 {
                replaceAllButton.properties.state = .normal
                replaceAllButton.reloadData()
                itemClick?(KMNBotaSearchTopItemKey.replaceAllText.rawValue)
            } else if idx == 2 {
                replaceButton.properties.state = .normal
                replaceButton.reloadData()
                itemClick?(KMNBotaSearchTopItemKey.replaceText.rawValue)
            }
        }
        centerView_.valueDidChange = { [unowned self] value, _ in
            if let data = value as? String {
                replaceValueDidChange?(replaceInput, [.newKey : replaceInput.properties.text])
            }
        }
        
        bottomBox.isHidden = true
        bottomBox.borderWidth = 0
        bottomBox.contentView?.addSubview(resultLabel_)
        resultLabel_.km_add_top_constraint(constant: 16)
        resultLabel_.km_add_leading_constraint(constant: 16)
        
        bottomBox.contentView?.addSubview(nextButton_)
        nextButton_.km_add_trailing_constraint(constant: -16)
        nextButton_.km_add_top_constraint(constant: 16)
        nextButton_.km_add_size_constraint(size: .init(width: 16, height: 16))
        
        bottomBox.contentView?.addSubview(previousButton_)
        previousButton_.km_add_trailing_constraint(equalTo: nextButton_, attribute: .leading, constant: -8)
        previousButton_.km_add_top_constraint(constant: 16)
        previousButton_.km_add_size_constraint(size: .init(width: 16, height: 16))
    }
    
    func showSearch() {
        centerBox.isHidden = true
        
        centerHeightConst.constant = 0
    }
    
    func showReplace() {
        centerBox.isHidden = false
        
        centerHeightConst.constant = centerHeight_
    }
    
    func showResult(type: KMNBotaSearchType) {
        bottomBox.isHidden = false
    }
    
    func hideResult(type: KMNBotaSearchType) {
        bottomBox.isHidden = true
    }
    
    func fetchContentHeight(type: KMNBotaSearchType, hasResult: Bool) -> CGFloat {
        var height: CGFloat = topHeight_
        if type == .search {
            
        } else if type == .replace {
            height += centerHeight_
        }
        
        height += (hasResult ? bottomHeight_+vSpace_ : 0)
        return height
    }
    
    // MARK: - Actions
    
    @objc func searchAction() {
        itemClick?(KMNBotaSearchTopItemKey.search.rawValue, searchButton_)
    }
    
    @objc func replaceAction() {
        itemClick?(KMNBotaSearchTopItemKey.replace.rawValue)
    }
    
    @objc func switchAction() {
        itemClick?(KMNBotaSearchTopItemKey.switch.rawValue)
    }
    
    @objc func previousAction() {
        itemClick?(KMNBotaSearchTopItemKey.previous.rawValue)
    }
    
    @objc func nextActon() {
        itemClick?(KMNBotaSearchTopItemKey.next.rawValue)
    }
}

extension KMNBotaSearchTopView: NSTextFieldDelegate {
    func controlTextDidChange(_ obj: Notification) {
        if searchInput_.isEqual(to: obj.object) {
            valueDidChange?(searchInput_, [.newKey : searchInput_.stringValue])
        }
    }
    
    func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
        if control == searchInput_, commandSelector == #selector(NSResponder.insertNewline(_:)) {
            print("Enter 键被按下 (来自 searchInput_)")
            print(searchInput_.stringValue)
            // 在这里执行你需要的操作,例如通知外部
            enterAction?(searchInput_.stringValue)
            return true  // 阻止默认行为
        }
        return false
    }
}