//
//  KMWatermarkAdjectiveBaseController.swift
//  PDF Master
//
//  Created by tangchao on 2022/12/15.
//

import Cocoa

class KMWatermarkTestWindow: NSWindow {
    
    var controller: KMWatermarkAdjectivePreViewBaseController!
    
    override init(contentRect: NSRect, styleMask style: NSWindow.StyleMask, backing backingStoreType: NSWindow.BackingStoreType, defer flag: Bool) {
        super.init(contentRect: contentRect, styleMask: style, backing: backingStoreType, defer: flag);
        
        isReleasedWhenClosed = false
        
        let controller_: KMCropPreviewController = KMCropPreviewController()
        contentView?.addSubview(controller_.view)
        controller_.view.frame = CGRect(x: 0, y: 0, width: contentRect.size.width, height: contentRect.size.height)
        controller = controller_
    }
    
}

typealias KMWatermarkAdjectivePageNumberViewCallback = (_ value: String) -> ()
class KMWatermarkAdjectivePageNumberView: NSView , NSTextFieldDelegate{
    var numberTextField = NSTextField()
    var rightLabel = NSTextField(labelWithString: "")
    
    var callback: KMWatermarkAdjectivePageNumberViewCallback?
    
    override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        
        self.initSubViews()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        
        self.initSubViews()
    }
    
    func initSubViews() {
        self.addSubview(self.numberTextField)
        self.addSubview(self.rightLabel)
        
        self.numberTextField.alignment = .center
        self.rightLabel.alignment = .left
        self.numberTextField.textColor = NSColor.white
        self.rightLabel.textColor = NSColor.white
        self.numberTextField.isBordered = false
        self.numberTextField.drawsBackground = false
        self.numberTextField.focusRingType = .none
        self.numberTextField.delegate = self
        self.numberTextField.formatter = TextFieldFormatter()
        self.numberTextField.maximumNumberOfLines = 1
        self.numberTextField.lineBreakMode = .byTruncatingTail
    }
    
    override func layout() {
        super.layout()
        
        let width: CGFloat = NSWidth(self.bounds)
        let height: CGFloat = NSHeight(self.bounds)
        
        let contentH: CGFloat = 20
        let contentY: CGFloat = (height-contentH) * 0.5
        self.numberTextField.frame = NSRect(x: 10, y: contentY, width: width * 0.5-10, height: contentH)
        self.rightLabel.frame = NSRect(x: width * 0.5, y: contentY, width: width * 0.5, height: contentH)
    }
    
    func controlTextDidChange(_ obj: Notification) {
        if (self.numberTextField.isEqual(to: obj.object)) {
            guard let callback = self.callback else {
                return
            }
            
            callback(self.numberTextField.stringValue)
        }
    }
}

typealias KMWatermarkAdjectivePreViewItemClick = (_ index: Int, _ param: Any?) -> ()

/// 水印相关 预览控制器(基类)
class KMWatermarkAdjectivePreViewBaseController: NSViewController {

    @IBOutlet weak var topBarBox: NSBox!
    lazy var topBarView: KMWatermarkAdjectiveTopBarView = {
        let view = KMWatermarkAdjectiveTopBarView()
        return view
    }()
    
    @IBOutlet weak var splitView: NSSplitView!
    
    @IBOutlet weak var pageInputBox: NSBox!
    @IBOutlet weak var preViewBox: NSBox!
    var preView: CPDFView!
    var documentURL: URL!
    var applyDocument: CPDFDocument?
    
    var pageNumberView = KMWatermarkAdjectivePageNumberView()
    
    var watermarkArray: Array<KMWatermarkModel> = []
    
    @IBOutlet weak var rightBox: NSBox!
    var rightViewController: NSViewController!
    
    @IBOutlet weak var tipBox: NSBox!
    
    private var maskView: NSButton!
    private var indicator: NSProgressIndicator!
    
    var itemClick: KMWatermarkAdjectivePreViewItemClick?
    var model: KMWatermarkAdjectiveBaseModel?
    
    init() {
        super.init(nibName: "KMWatermarkAdjectivePreViewBaseController", bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        super.init(nibName: "KMWatermarkAdjectivePreViewBaseController", bundle: nil)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.topBarView.frame = self.topBarBox.contentView!.bounds
        self.topBarView.autoresizingMask = NSView.AutoresizingMask(rawValue: 18)
        self.topBarBox.contentView?.addSubview(self.topBarView)
        self.topBarBox.fillColor = NSColor.white
        
        self.view.wantsLayer = true
        self.view.layer?.backgroundColor = NSColor.white.cgColor
        
        self.topBarView.isCanApply(can: false)
        self.topBarView.cancelClick = {
            [unowned self] in
            self.cancelAction()
        }
        
        self.topBarView.applyClick = {
            [unowned self] in
            self.applyAction()
        }
        
        self.topBarView.itemClick = { [weak self] section, item in
            self!.topItemClick(index: item)
        }
        
        self.rightBox.fillColor = NSColor(white: 243.0/255.0, alpha: 1.0)
        self.splitView.isVertical = true
        self.splitView.dividerStyle = .thin
        self.splitView.delegate = self
//        self.splitView.arrangedSubviews.first?.frame = NSMakeRect(0, 0, self.splitView.frame.size.width-260, self.splitView.frame.size.height)
//        self.splitView.arrangedSubviews.last?.frame = NSMakeRect(self.splitView.frame.size.width-260, 0, 260, self.splitView.frame.size.height)
     
        let pageNumberView = self.pageNumberView
        pageNumberView.frame = self.pageInputBox.contentView!.bounds
        pageNumberView.autoresizingMask = [.width, .height]
        self.pageInputBox.contentView?.addSubview(pageNumberView)
        self.pageInputBox.fillColor = NSColor.black
        
        self.pageNumberView.callback = { [weak self] string in
            var number: Int = 0
            if (string.isEmpty) {
                number = 1
            } else {
                number = Int(string)!
                if (number <= 0) {
                    number = 1
                } else if (number > (self?.preView.document.pageCount)!) {
                    number = Int((self?.preView.document.pageCount)!)
                }
            }
            
            self?.pageNumberView.numberTextField.stringValue = "\(number)"
            self?.preView.go(toPageIndex: number-1, animated: true)
        }
    }
    
    override func viewWillAppear() {
        super.viewWillAppear()
        
        if (self.documentURL != nil) {
            self.preView.document = CPDFDocument(url: self.documentURL)
            
            self.pageNumberView.numberTextField.stringValue = "1"
            self.pageNumberView.rightLabel.stringValue = "/   \(self.preView.document.pageCount)"
        }
    }
    
    func cancelAction() {
        guard let callback = self.itemClick else {
            return
        }
        
        callback(0, nil)
    }
    
    func applyAction() {
        
    }
    
    func topItemClick(index: Int) {
        
    }
    
    func right_gotoViewController(viewController: NSViewController) {
        for subview in self.rightBox.contentView!.subviews {
            subview.removeFromSuperview()
        }
        
        viewController.view.frame = self.rightBox.contentView!.bounds
        viewController.view.autoresizingMask = NSView.AutoresizingMask(rawValue: 18)
        self.rightBox.contentView?.addSubview(viewController.view)
        self.rightViewController = viewController
    }

    func addWatermark(model: KMWatermarkModel, toPath: String, completion: @escaping (_ result: Bool) -> ()) {
        DispatchQueue.global().async {
            var property: CPDFWatermark!
            var scale: CGFloat = model.scale
            if (!model.text.isEmpty) {
                property = CPDFWatermark(document: self.preView.document, type: .text)
                property.text = model.text
                property.textColor = model.getTextColor()
                scale = model.getTextFontSize() / 24.0
            } else {
                property = CPDFWatermark(document: self.preView.document, type: .image)
                property.image = model.image
            }
            
            property.scale = scale
            property.rotation = -model.rotation
            property.opacity = model.opacity
            property.tx = model.horizontalSpace
            property.ty = model.verticalSpace
            property.isFront = model.isFront
            var pageString: String = ""
            if (model.pageRangeType == 0) {
                for i in 0 ..< self.preView.document.pageCount {
                    pageString.append("\(i)")
                    
                    if (i != self.preView.document.pageCount-1) {
                        pageString.append(",")
                    }
                }
            } else if (model.pageRangeType == 1) {
                for i in 0 ..< self.preView.document.pageCount {
                    if (i % 2 == 0) {
                        pageString.append("\(i)")
                    } else {
                        continue
                    }
                    
                    if (i != self.preView.document.pageCount-1) {
                        pageString.append(",")
                    }
                }
            } else if (model.pageRangeType == 2) {
                for i in 0 ..< self.preView.document.pageCount {
                    if (i % 2 == 1) {
                        pageString.append("\(i)")
                    } else {
                        continue
                    }
                    
                    if (i != self.preView.document.pageCount-1) {
                        pageString.append(",")
                    }
                }
            } else {
                pageString = model.pagesString
            }
            property.pageString = pageString
            property.isTilePage = model.isTilePage
            property.horizontalSpacing = model.tileHorizontalSpace / scale
            property.verticalSpacing = model.tileVerticalSpace / scale
            if (model.verticalMode == 0) {
                property.verticalPosition = .top
            } else if (model.verticalMode == 1) {
                property.verticalPosition = .center
            } else if (model.verticalMode == 2) {
                property.verticalPosition = .bottom
            }
            
            if (model.horizontalMode == 0) {
                property.horizontalPosition = .left
            } else if (model.horizontalMode == 1) {
                property.horizontalPosition = .center
            } else if (model.horizontalMode == 2) {
                property.horizontalPosition = .right
            }
            model.watermark = property
            
            self.preView.document.addWatermark(property)
            
            /// 保存到临时路径
            let documentPath = NSTemporaryDirectory()
            let tempPath: String = "\(documentPath)/\(toPath.lastPathComponent)"
            if (FileManager.default.fileExists(atPath: tempPath)) {
                try?FileManager.default.removeItem(atPath: tempPath)
            }
            
            let result = self.preView.document.write(to: URL(fileURLWithPath: tempPath))
            if (result) {
                if (FileManager.default.fileExists(atPath: toPath)) {
                    try?FileManager.default.removeItem(atPath: toPath)
                }
                
                try?FileManager.default.moveItem(atPath: tempPath, toPath: toPath)
            } else {
                try?FileManager.default.removeItem(atPath: tempPath)
            }
            
            DispatchQueue.main.async {
                completion(result)
            }
        }
        
        func loadAllWatermarks() {
            self.watermarkArray.removeAll()
            let watermarks: Array<CPDFWatermark> = self.preView.document.watermarks()
            for watermark in watermarks {
                let model = KMWatermarkModel()
                model.scale = watermark.scale
                model.rotation = -watermark.rotation
                model.opacity = watermark.opacity
                model.verticalSpace = watermark.tx
                model.horizontalSpace = watermark.ty
                model.pagesString = watermark.pageString
//                model.textColor = watermark.textColor
                model.isFront = watermark.isFront
                model.isTilePage = watermark.isTilePage
                model.tileVerticalSpace = watermark.verticalSpacing
                model.tileHorizontalSpace = watermark.horizontalSpacing
                
                if (watermark.type == .text) {
                    model.text = watermark.text
//                    model.textFont
                    model.scale = watermark.scale * 24
                } else if (watermark.type == .image) {
                    model.image = watermark.image
                }
                
                if (watermark.verticalPosition == .top) {
                    model.verticalMode = 0
                } else if (watermark.verticalPosition == .center) {
                    model.verticalMode = 1
                } else if (watermark.verticalPosition == .bottom) {
                    model.verticalMode = 2
                }
                
                if (watermark.horizontalPosition == .left) {
                    model.horizontalMode = 0
                } else if (watermark.horizontalPosition == .center) {
                    model.horizontalMode = 1
                } else if (watermark.horizontalPosition == .right) {
                    model.horizontalMode = 2
                }
                
                model.watermark = watermark
                self.watermarkArray.append(model)
            }
        }
    }
    
    func deleteWatermarks(toPath: String, completion: @escaping (_ result: Bool) -> ()) -> () {
        if (self.preView.document.watermarks().count <= 0) {
            completion(false)
        }
        DispatchQueue.global().async {
            let array: Array<CPDFWatermark> = self.preView.document.watermarks()
            for model in array {
                self.preView.document.removeWatermark(model)
            }

            /// 保存到临时路径
            let documentPath = NSTemporaryDirectory()
            let tempPath: String = "\(documentPath)/\(toPath.lastPathComponent)"
            if (FileManager.default.fileExists(atPath: tempPath)) {
                try?FileManager.default.removeItem(atPath: tempPath)
            }

            let result = self.preView.document.write(to: URL(fileURLWithPath: tempPath))
            if (result) {
                if (FileManager.default.fileExists(atPath: toPath)) {
                    try?FileManager.default.removeItem(atPath: toPath)
                }

                try?FileManager.default.moveItem(atPath: tempPath, toPath: toPath)
            } else {
                try?FileManager.default.removeItem(atPath: tempPath)
            }

            DispatchQueue.main.async {
                completion(result)
            }
        }
    }
    
    /// 开始加载loading
    func beginLoading() {
        DispatchQueue.main.async { [self] in
            self.maskView = NSButton()
            self.maskView.isBordered = false
            self.maskView.title = ""
            self.maskView.wantsLayer = true
            self.maskView.layer?.backgroundColor = NSColor(white: 1, alpha: 0.3 ).cgColor
            self.maskView.target = self
            self.maskView.action = #selector(maskViewClick)
            self.maskView.frame = (self.view.bounds)
            self.maskView.autoresizingMask = NSView.AutoresizingMask(rawValue: 18)
            self.view.addSubview(self.maskView)
            
            self.indicator = NSProgressIndicator()
            self.indicator.style = .spinning
            self.indicator.controlSize = .regular
            self.indicator.isIndeterminate = true
            self.view.addSubview(self.indicator)
            let indicatorSize: CGFloat = 32
            self.indicator.frame = NSMakeRect(0.5*(NSWidth((self.view.frame))-indicatorSize), 0.5*(NSHeight((self.view.frame))-indicatorSize), indicatorSize, indicatorSize)
            self.maskView.autoresizingMask = NSView.AutoresizingMask(rawValue: 45)
            
            self.indicator.startAnimation(nil)
        }
    }
    
    /// 结束加载loading
    func endLoading() {
        DispatchQueue.main.async {
            self.indicator.stopAnimation(nil)
            
            self.indicator.removeFromSuperview()
            self.indicator = nil
            
            self.maskView.removeFromSuperview()
            self.maskView = nil
        }
    }
    
    @objc func maskViewClick() {
        
    }
    
    func findPagesString(_ model: KMWatermarkAdjectiveBaseModel) -> String{
        if (model.pageRangeType == 0) { /// 全部页面
            return "0-\(model.pageCount-1)"
        } else if (model.pageRangeType == 1) { /// 奇数页面
            var string: String = ""
            for i in 0 ..< model.pageCount {
                if (i % 2 == 1) {
                    continue
                }
                
                string.append("\(i)")
                if (i != model.pageCount-1) {
                    string.append(",")
                }
            }
            return string
        } else if (model.pageRangeType == 2) { /// 偶数页面
            var string: String = ""
            for i in 0 ..< model.pageCount {
                if (i % 2 == 0) {
                    continue
                }
                
                string.append("\(i)")
                if (i != model.pageCount-1) {
                    string.append(",")
                }
            }
            return string
        } else { /// 自定义
            return model.pageRangeString
        }
    }
}

extension KMWatermarkAdjectivePreViewBaseController: NSSplitViewDelegate {
//    func splitView(_ splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
//        if (dividerIndex == 0) {
//            return NSWidth(splitView.frame)-260
//        }
//        return proposedMinimumPosition
//    }
//
//    func splitView(_ splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
//        if (dividerIndex == 0) {
//            return NSWidth(splitView.frame)-260
//        }
//        return proposedMaximumPosition
//    }
    func splitView(_ splitView: NSSplitView, shouldAdjustSizeOfSubview view: NSView) -> Bool {
        return true
    }
    
    func splitView(_ splitView: NSSplitView, shouldHideDividerAt dividerIndex: Int) -> Bool {
        return true
    }
    
    func splitView(_ splitView: NSSplitView, resizeSubviewsWithOldSize oldSize: NSSize) {
        let dividerThickness: CGFloat = splitView.dividerThickness
        var leftRect: NSRect = splitView.subviews.first!.frame
        var rightRect: NSRect = splitView.subviews.last!.frame
        
        let newFrame: NSRect = splitView.frame
        rightRect.size.height = newFrame.size.height
        leftRect.origin.x = 0
        leftRect.size.width = newFrame.size.width-rightRect.size.width-dividerThickness
        leftRect.size.height = newFrame.size.height
        rightRect.origin.x = leftRect.size.width
        
        splitView.subviews.first?.frame = leftRect
        splitView.subviews.last?.frame = rightRect
    }
}