//
//  KMCustomViewButton.swift
//  PDF Reader Pro
//
//  Created by tangchao on 2023/11/2.
//

import Cocoa
@objc enum KMCustomViewButtonType: Int {
    case batchToolbar = 0
    case menuItem
    case normal
}

@objc enum KMCustomViewButtonState: Int {
    case normal = 0
    case mouseIn
    case hightLighted
}

@objc protocol KMCustomButtonViewPopDataSource: NSObjectProtocol {
    /// pop框有多少行
    func numberOfLine(in button: KMCustomViewButton) -> Int
    /// pop框某行显示的文字
    func string(for button: KMCustomViewButton, index: Int) -> String?
    /// 某行是否需要下划线
    func needInsertSeperateLine(_ button: KMCustomViewButton, index: Int) -> Bool
    /// 某行是否需要选取
    func needHightLightLine(_ button: KMCustomViewButton, index: Int) -> Bool
}

@objc protocol KMCustomButtonViewPopDelegate: NSObjectProtocol {
    func customViewButton(_ button: KMCustomViewButton, didSelectIndex index: Int)
}

@objcMembers class KMCustomViewButton: NSView {
    /// constraint
    var frontImageLeftConstraint: MASConstraint? //左边图片距离左边约束
    var frontImageTopConstraint: MASConstraint? //左边图片顶部约束
    var titleLeftConstraint: MASConstraint? //标题距离左边约束
    var titleTopConstraint: MASConstraint? //标题顶部约束
    var backImageLeftConstraint: MASConstraint? //右边图片距离左边约束
    
    /// view
    lazy var imageView: NSImageView = {
        let view = NSImageView()
        return view
    }()
    lazy var titleTextField: NSTextField = {
        let view = NSTextField()
        view.isBordered = false
        view.drawsBackground = true
        view.backgroundColor = .clear
        view.isEditable = false
        return view
    }()
    lazy var indicateImageView: NSImageView = {
        let view = NSImageView()
        return view
    }()
    weak var layoutReferenceView: NSView?
    
    /// layer
    var backLayer: CALayer?
    
    /// state
    var isSelected = false {
        didSet {
            if (self.isSelected) {
                self._toolbarButtonSelected(true)
                if let color = self.selectColor {
                    self.backLayer?.backgroundColor = color.cgColor
                }
            } else {
                self._toolbarButtonSelected(true)
                self.backLayer?.backgroundColor = .clear
            }
        }
    }
    
    var mouseInColor: NSColor?
    var highLightColor: NSColor?
    var selectColor: NSColor?
    
    /// popover
    var popOver: NSPopover?
    
    var enable = false
    
    /// title Attribute
    var titleAttributeDict: [String : Any]?
    
    weak var dataSource: KMCustomButtonViewPopDataSource? {
        didSet {
            NotificationCenter.default.removeObserver(self)
            NotificationCenter.default.addObserver(self, selector: #selector(_closePop), name: NSNotification.Name("KMCloseCustomViewButtonPopNotification"), object: nil)
        }
    }
    weak var delegate: KMCustomButtonViewPopDelegate?
    
    private var _showMenuFlag = false
    
    private var _type: KMCustomViewButtonType = .batchToolbar
    private var _state: KMCustomViewButtonState = .normal {
        didSet {
            if (self._state == .normal) {
                if (self.isSelected) {
                    self.backLayer?.backgroundColor = self.selectColor != nil ? self.selectColor!.cgColor : .clear
                } else {
                    self._toolbarButtonSelected(true)
                    self.backLayer?.backgroundColor = .clear
                }
            } else if (self._state == .mouseIn) {
                self._toolbarButtonSelected(true)
                if (self.isSelected) {
                    self.backLayer?.backgroundColor = self.selectColor != nil ? self.selectColor!.cgColor : (self.mouseInColor ?? NSColor.clear).cgColor
                } else {
                    self.backLayer?.backgroundColor = (self.mouseInColor ?? NSColor.clear).cgColor
                }
            } else if (self._state == .hightLighted) {
                if (self.isSelected) {
                    self.backLayer?.backgroundColor = self.selectColor != nil ? self.selectColor!.cgColor : (self.highLightColor ?? NSColor.clear).cgColor
                } else {
                    self.backLayer?.backgroundColor = (self.highLightColor ?? NSColor.clear).cgColor
                }
            }
            
            if (self.titleAttributeDict != nil) {
                self.titleTextField.textColor = self.titleAttributeDict?["\(self._state.rawValue)"] as? NSColor
            }
        }
    }
    
    private weak var _target: AnyObject?
    private var _action: Selector?
    
    deinit {
        KMPrint("KMCustomViewButton deinit.")
        NotificationCenter.default.removeObserver(self)
    }
    
    /**
     * 初始化方法
     * @param frontImage 头部图片
     * @param backImage 尾部图片
     * @param title 标题
     * @param title 样式
     *
     */
    convenience init(frontImage: NSImage?, backImage: NSImage?, title: String?, type: KMCustomViewButtonType) {
        if frontImage == nil && backImage == nil && title == nil {
//            return
        }
        self.init()
        self.wantsLayer = true
        self.enable = false
        
        self._addTrackingArea()
        self.layoutReferenceView = self
        var leftMargin = 0.0
         if (frontImage != nil) {
             self.addSubview(self.imageView)
             self.imageView.image = frontImage
             leftMargin = 8
             self.imageView.mas_makeConstraints { make in
                 self.frontImageLeftConstraint = make?.left.equalTo()(self.layoutReferenceView)?.offset()(leftMargin)
                 make?.centerY.top().equalTo()(self.layoutReferenceView)
                 self.frontImageTopConstraint = make?.top.equalTo()(self.layoutReferenceView)?.offset()(3)
             }
             self.layoutReferenceView = self.imageView
         }
        
        if (title != nil) {
            self.addSubview(self.titleTextField)
            self.titleTextField.stringValue = title!
            self.titleTextField.font = .systemFont(ofSize: 12)
            self.titleTextField.textColor = KMAppearance.Layout.h0Color()
            self.titleTextField.mas_makeConstraints { make in
                if self.isEqual(to: self.layoutReferenceView) {
                    leftMargin = 30
                    self.titleLeftConstraint = make?.left.equalTo()(self)?.offset()(leftMargin)
                    self.titleTopConstraint = make?.top.equalTo()(self)?.offset()(3)
                    make?.centerY.equalTo()(self)
                } else {
                    leftMargin = 8
                    self.titleLeftConstraint = make?.left.equalTo()(self.imageView.mas_right)?.offset()(leftMargin)
                    make?.centerY.equalTo()(self)
                }
            }
            self.layoutReferenceView = self.titleTextField
        }
        
        if (backImage != nil) {
            self.addSubview(self.indicateImageView)
            self.indicateImageView.image = backImage
            self.indicateImageView.mas_makeConstraints { make in
                self.backImageLeftConstraint = make?.left.equalTo()(self.layoutReferenceView?.mas_right)?.offset()(2)
                make?.centerY.equalTo()(self)
            }
            self.layoutReferenceView = self.indicateImageView
        }
        
        self.layoutReferenceView?.mas_makeConstraints({ make in
            make?.right.equalTo()(self)?.offset()(-leftMargin)
        })
        self.configuAppearance(type: type)
        self._type = type
        self._state = .normal
        self.isSelected = false
    }
    
    override func mouseEntered(with event: NSEvent) {
        if (self.enable) {
            super.mouseEntered(with: event)
            self._showPop()
            if (self.dataSource == nil) {
                NotificationCenter.default.post(name: NSNotification.Name("KMCloseCustomViewButtonPopNotification"), object: nil)
            }
            self._state = .mouseIn
        }
    }
    
    // MARK: - Public Methods
    
    /// 设置设置target-action
    func addTarget(_ target: AnyObject?, action: Selector?) {
        self._target = target
        self._action = action
    }
    
    /// 关闭pop
    func closePop() {
        self._closePop()
    }
    
    override func mouseExited(with event: NSEvent) {
        if (self.enable) {
            super.mouseExited(with: event)
            if (self._showMenuFlag) {
            } else {
                self._state = .normal
            }
        }
    }
    
    override func mouseDown(with event: NSEvent) {
        if (self.enable) {
            super.mouseDown(with: event)
            self._state = .hightLighted
        }
    }
    
    override func mouseUp(with event: NSEvent) {
        if (self.enable) {
            super.mouseUp(with: event)
            if (self._showMenuFlag) {
            } else {
                self._state = .normal
            }
            /// 响应事件
            if let data = (self._target as? NSObject)?.responds(to: self._action), data {
                (self._target as? NSObject)?.perform(self._action, with: self)
            }
        }
    }
}

// MARK: - Private Methods

extension KMCustomViewButton {
    private func _toolbarButtonSelected(_ isSelected: Bool) {
        //    if (isSelected) {
        //        if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Convert", nil)]) {
        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchConvert"];
        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Merge", nil)]) {
        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchMerge"];
        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Compress", nil)]) {
        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchOptimize"];
        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"OCR", nil)]) {
        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchConvertOCR"];
        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Security", nil)]) {
        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchSafe"];
        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Watermark", nil)]) {
        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchWatermark"];
        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Background", nil)]) {
        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchBackground"];
        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Header & Footer", nil)]) {
        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchHeaderandfooter"];
        //        } else if ([self.titleTextField.stringValue isEqualToString:NSLocalizedString(@"Bates Numbers", nil)]) {
        //            self.imageView.image = [NSImage imageNamed:@"KMImageNameUXIconBatchBates"];
        //        }
        //    } else {
        if self.titleTextField.stringValue == KMLocalizedString("Convert", nil) {
            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchConvertNor")
        } else if self.titleTextField.stringValue == KMLocalizedString("Merge", nil) {
            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchMergeNor")
        } else if self.titleTextField.stringValue == KMLocalizedString("Compress", nil) {
            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchOptimizeNor")
        } else if self.titleTextField.stringValue == KMLocalizedString("OCR", nil) {
            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchConvertOCRNor")
        } else if self.titleTextField.stringValue == KMLocalizedString("Security", nil) {
            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchSafeNor")
        } else if self.titleTextField.stringValue == KMLocalizedString("Watermark", nil) {
            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchWatermarkNor")
        } else if self.titleTextField.stringValue == KMLocalizedString("Background", nil) {
            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchBackgroundNor")
        } else if self.titleTextField.stringValue == KMLocalizedString("Header & Footer", nil) {
            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchHeaderandfooterNor")
        } else if self.titleTextField.stringValue == KMLocalizedString("Bates Numbers", nil) {
            self.imageView.image = NSImage(named: "KMImageNameUXIconBatchBatesNor")
        }

        //    }
    }
    
    @objc private func _closePop() {
        self.popOver?.close()
        self._state = .normal
    }
    
    private func _showPop() {
        if (self.delegate == nil || self.dataSource == nil) {
            return
        }
        
        let menuViewController = KMCustomButtonPopMenuViewController()
        menuViewController.delegate = self
        menuViewController.dataSources = self
        if (self.popOver == nil) {
            self.popOver = NSPopover()
        }
        
        self.popOver?.delegate = self
        self.popOver?.contentViewController = menuViewController
        self.popOver?.animates = false
        self.popOver?.behavior = .semitransient
        self.popOver?.contentSize = menuViewController.view.frame.size
        
        var sourcesRect = self.bounds
        sourcesRect = self.convert(sourcesRect, to: nil)
        sourcesRect.origin.y -= 20
        sourcesRect.size.height+=20
        self.window?.popover = self.popOver
        self.window?.sourcesRect = sourcesRect
        self.popOver?.show(relativeTo: CGRectInset(self.bounds, 0, 5), of: self, preferredEdge: .minY)
    }
    
    private func _addTrackingArea() {
        let trackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .inVisibleRect, .activeAlways,.mouseMoved], owner: self)
        self.addTrackingArea(trackingArea)
    }
}

// MARK: - NSPopoverDelegate

extension KMCustomViewButton: NSPopoverDelegate {
    func popoverDidShow(_ notification: Notification) {
        self._showMenuFlag = true
    }
    
    func popoverDidClose(_ notification: Notification) {
        self._showMenuFlag = false
        self._state = .normal
    }
}

// MARK: - KMCustomButtonPopMenuViewControllerDelegate, KMCustomButtonPopMenuViewControllerDataSources

extension KMCustomViewButton: KMCustomButtonPopMenuViewControllerDelegate, KMCustomButtonPopMenuViewControllerDataSources {
    func customViewButtonPopDidSelectIndex(_ index: Int) {
        if let _ = self.delegate?.customViewButton(self, didSelectIndex: index) {
            self._closePop()
        }
    }
    
    func numberOfLine() -> Int {
        if let data = self.dataSource?.numberOfLine(in: self) {
            return data
        }
        return 0
    }
    
    /// pop框某行显示的文字
    func stringForLine(at index: Int) -> String? {
        if let data = self.dataSource?.string(for: self, index: index) {
            return data
        }
        return nil;
    }
    
    /// 某行是否需要下划线
    func needInsertSeperateLine(at index: Int) -> Bool {
        if let data = self.dataSource?.needInsertSeperateLine(self, index: index) {
            return data
        }
        return false
    }
    
    /// 某行是否需要选取
    func needHightLightLine(at index: Int) -> Bool {
        if let data = self.dataSource?.needHightLightLine(self, index: index) {
            return data
        }
        return false
    }
    
    func imageForLine(at index: Int) -> NSImage? {
        return nil
    }
    
    func itemEnable(at index: Int) -> Bool {
        return true
    }
}

// MARK: - Appearance

extension KMCustomViewButton {
    func configuAppearance(type: KMCustomViewButtonType) {
        if (type == .batchToolbar) {
            self.backLayer = CALayer()
            self.backLayer?.frame = self.layer?.frame ?? NSRect.zero
            self.backLayer?.autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
            self.layer?.addSublayer(self.backLayer!)
            self.backLayer?.cornerRadius = 6.0;
            self.selectColor = KMAppearance.Status.selColor()
            self.highLightColor = KMAppearance.Status.selColor()
            self.mouseInColor = KMAppearance.Status.selColor()
        } else if (type == .menuItem) {
            self.alignCenter(margin: 10)
            self.changeTopMargin(5)
        }
    }
    
    /// 调整按钮左右间距并居中
    func alignCenter(margin: CGFloat) {
        self.changeLeftMargin(margin)
        self.changeRightMargin(margin)
    }
    
    /// 调整顶部间距离
    func changeTopMargin(_ topMargin: CGFloat) {
        let v = self._leftestView()
        if self.imageView.isEqual(to: v) {
            self.imageView.mas_updateConstraints { make in
                make?.top.equalTo()(self)?.offset()(topMargin)
            }
        } else if self.titleTextField.isEqual(to: v) {
            self.titleTextField.mas_updateConstraints { make in
                make?.top.equalTo()(self)?.offset()(topMargin)
            }
        } else if self.indicateImageView.isEqual(to: v) {
            
        }
    }
    /// 调整按钮左边间距
    func changeLeftMargin(_ leftMargin: CGFloat) {
        let v = self._leftestView()
        if self.imageView.isEqual(to: v) {
            self.imageView.mas_updateConstraints { make in
                self.frontImageLeftConstraint = make?.left.equalTo()(self)?.offset()(leftMargin)
            }
        } else if self.titleTextField.isEqual(to: v) {
            self.titleTextField.mas_updateConstraints { make in
                self.titleLeftConstraint = make?.left.equalTo()(self)?.offset()(leftMargin)
            }
        } else if self.indicateImageView.isEqual(to: v) {
            self.indicateImageView.mas_updateConstraints { make in
                self.backImageLeftConstraint = make?.left.equalTo()(self)?.offset()(leftMargin)
            }
        }
    }
    /// 调整按钮右边间距
    func changeRightMargin(_ rightMargin: CGFloat) {
        let v = self._rightestView()
        if self.imageView.isEqual(to: v) {
            self.imageView.mas_updateConstraints { make in
                make?.right.equalTo()(self)?.offset()(-rightMargin)
            }
        } else if self.titleTextField.isEqual(to: v) {
            self.titleTextField.mas_updateConstraints { make in
                make?.right.equalTo()(self)?.offset()(-rightMargin)
            }
        } else if self.indicateImageView.isEqual(to: v) {
            self.indicateImageView.mas_updateConstraints { make in
                make?.right.equalTo()(self)?.offset()(-rightMargin)
            }
        }
    }
    
    private func _leftestView() -> NSView? {
        if self.subviews.contains(self.imageView) {
            return self.imageView
        } else if self.subviews.contains(self.titleTextField) {
            return self.titleTextField
        } else if (self.subviews.contains(self.indicateImageView)) {
            return self.indicateImageView
        }
        return nil
    }
    
    private func _rightestView() -> NSView? {
        if self.subviews.contains(self.indicateImageView) {
            return self.indicateImageView
        } else if self.subviews.contains(self.titleTextField) {
            return self.titleTextField
        } else if self.subviews.contains(self.imageView) {
            return self.imageView
        }
        return nil
    }
}