//
//  KMBatchOperateAddHeaderFooterViewController.swift
//  PDF Master
//
//  Created by liujiajie on 2023/11/7.
//

import Cocoa

class KMBatchOperateAddHeaderFooterViewController: KMBatchOperateBaseViewController, NSTableViewDelegate,NSTableViewDataSource{
    var isBates = false
    var onlyManagerTemplate = false
    var isBatchOperation = false
    var pdfView: PDFView?
    
    @IBOutlet var topBaseView: NSView!
    @IBOutlet var bottomBaseView: NSView!
    @IBOutlet var tableView: NSTableView!
    @IBOutlet var titleLabel: NSTextField!
    @IBOutlet var actionButton: NSButton!
    @IBOutlet var managerTemplateTitleLabel: NSTextField!
    @IBOutlet var addButton: NSButton!
    @IBOutlet var blankView: KMBlankView!
    
    @IBOutlet var managerTemplateTopConstraint: NSLayoutConstraint!
    
    @IBOutlet var managerTemplateButtonHeightConstraint: NSButton!
    @IBOutlet var topHeightConstraint: NSLayoutConstraint!
    
    var haveFiles = false
    var currentObject: KMHeaderFooterObject?
    
    override var interfaceStatus: KMBatchOperateInterfaceStatus?{
        set{
            super.interfaceStatus = newValue
            if newValue == .PrepareProcess {
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
                    let files = NSMutableArray()
                    for url in self.successFilePathURLArray! {
                        if FileManager.default.fileExists(atPath: url.path) {
                            files.add(url)
                        }
                    }
                    if files.count > 0 {
                        let workspace = NSWorkspace.shared
                        workspace.activateFileViewerSelecting(files as! [URL])
                    }
                }
                self.actionButton.tag = 1
                self.actionButton.title = KMLocalizedString("Apply", nil)
                self.actionButton.setTitleColor(KMAppearance.Layout.w0Color())
            } else {
                self.actionButton.tag = 0
                self.actionButton.title = KMLocalizedString("Cancel", nil)
                self.actionButton.setTitleColor(KMAppearance.Layout.w0Color())
            }
        }
        get{
            return super.interfaceStatus
        }
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        localizedLanguage()
        configuInterface()
        NotificationCenter.default.addObserver(self, selector: #selector(headerFootersNotification(notification:)), name: Notification.Name(rawValue: "KMBatchOperateHeaderFootersNotification"), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(themeChanged(notification:)), name: Notification.Name(rawValue: "AppleInterfaceThemeChangedNotification"), object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(batchFilesCountNotification(notification:)), name: NSNotification.Name("KMBatchFilesCountNotification"), object: nil)
    }
    func localizedLanguage() {
        self.addButton.title = KMLocalizedString("Add Template", nil)
        self.actionButton.title = KMLocalizedString("Apply", nil)
        self.titleLabel.stringValue = KMLocalizedString("Apply", nil)
    }
    func configuInterface() {
        self.titleLabel.font = NSFont.systemFont(ofSize: 14)
        self.titleLabel.textColor = KMAppearance.Layout.h0Color()
        self.tableView.enclosingScrollView?.borderType = .noBorder
        self.actionButton.wantsLayer = true
        self.addButton.wantsLayer = true
        
        self.topHeightConstraint.constant = 0
        self.topBaseView.isHidden = true
        self.addButton.imagePosition = .imageLeft
        self.addButton.image = NSImage(named: "KMImageNameHeaderFooterAddBtn")
        self.addButton.layer?.backgroundColor = KMAppearance.Interactive.s0Color().cgColor
        self.addButton.setTitleColor(KMAppearance.Layout.h0Color())
        
        
        self.actionButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
        self.actionButton.setTitleColor(KMAppearance.Layout.w0Color())
        self.actionButton.imagePosition = .noImage
        if !self.onlyManagerTemplate {
            if self.files?.count ?? 0 > 0 {
                self.haveFiles = true
            } else {
                self.haveFiles = false
            }
        } else {
            self.haveFiles = true
        }
        updateActionButtonbackgroundColor()
        
        self.addButton.layer?.cornerRadius = 1.0
        self.actionButton.layer?.cornerRadius = 1.0
        
        self.topBaseView.wantsLayer = true
        self.topBaseView.layer?.backgroundColor = KMAppearance.Layout.l0Color().cgColor
        self.bottomBaseView.wantsLayer = true
        self.bottomBaseView.layer?.backgroundColor = KMAppearance.Layout.l0Color().cgColor
        self.managerTemplateTitleLabel.font = NSFont.systemFont(ofSize: 14)
        self.managerTemplateTitleLabel.textColor = KMAppearance.Layout.h0Color()
        
        self.titleLabel.isHidden = false
        self.addButton.isHidden = false
        self.managerTemplateTitleLabel.isHidden = true
        
        self.managerTemplateTitleLabel.stringValue = NSLocalizedString("Manage Templates", comment: "")
        
        self.view.addSubview(self.blankView)
        self.blankView.mas_makeConstraints { make in
            make?.top.equalTo()(self.topBaseView.mas_bottom)
            make?.left.equalTo()(self.view)
            make?.right.equalTo()(self.view)
            make?.bottom.equalTo()(self.bottomBaseView.mas_top)
            make?.height.greaterThanOrEqualTo()(200)
        }
        
        self.blankView.titleLabel.stringValue = KMLocalizedString("No Templates", nil)
        
        self.tableView.backgroundColor = KMAppearance.Layout.l0Color()
        
        let menu = NSMenu(title: "")
        if !self.isBatchOperation && !self.isBates {
            menu.addItem(withTitle: NSLocalizedString("Batch Add Header & Footer", comment: ""), action: #selector(buttonItemClick_addBatch(_:)), keyEquivalent: "")
        } else if !self.isBatchOperation && self.isBates {
            menu.addItem(withTitle: NSLocalizedString("Batch Add Bates Numbers", comment: ""), action: #selector(buttonItemClick_addBatch(_:)), keyEquivalent: "")
        }
        if !self.isBates {
            menu.addItem(withTitle: NSLocalizedString("Remove All Header & Footer Templates", comment: ""), action: #selector(buttonItemClick_CleanAll(_:)), keyEquivalent: "")
        } else {
            menu.addItem(withTitle: NSLocalizedString("Remove All Bates Numbers Templates", comment: ""), action: #selector(buttonItemClick_CleanAll(_:)), keyEquivalent: "")
        }
        self.view.menu = menu
        
        updateViewColor()
    }
    func updateActionButtonbackgroundColor() {
        let row = self.tableView.selectedRow 
        if (self.files?.count ?? 0 > 0 || self.pdfView != nil) && row > -1 {
            self.actionButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().cgColor
            self.actionButton.setTitleColor(KMAppearance.Layout.w0Color())
        } else {
            self.actionButton.setTitleColor(KMAppearance.Layout.w0Color().withAlphaComponent(0.6))
            self.actionButton.layer?.backgroundColor = KMAppearance.Interactive.m0Color().withAlphaComponent(0.6).cgColor
        }
    }
    @objc func buttonItemClick_addBatch(_ sender: Any) {
        let baseWindowController = KMBatchOperateBaseWindowController(windowNibName: "KMBatchOperateBaseWindowController")
        if #available(macOS 10.13, *) {
            baseWindowController.window?.makeKeyAndOrderFront(nil)
        } else {
            baseWindowController.showWindow(nil)
        }
        var arr = NSMutableArray()
        let file = KMBatchOperateFile(filePath: self.pdfView!.document!.documentURL!.path, type: self.isBates ? .AddBates : .AddHeaderFooter)
        arr.add(file)
        baseWindowController.checkNeedPasswordSwitchToOperateType(operateType: self.isBates ? .AddBates : .AddHeaderFooter, files: arr as! [KMBatchOperateFile])
    }
    @objc func buttonItemClick_CleanAll(_ sender: Any) {
        let alert = NSAlert()
        alert.alertStyle = .warning
        alert.messageText = ""
        alert.informativeText = NSLocalizedString("Are you sure to delete all templates?", comment: "")
        alert.addButton(withTitle: NSLocalizedString("Delete", comment: ""))
        alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
        alert.beginSheetModal(for: NSApp.mainWindow!) { (response) in
            if response == .alertFirstButtonReturn {
                self.deleteAll()
            }
        }
    }
    @objc func headerFootersNotification(notification: Notification) {
        if let addHeaderFooter = notification.object as? KMBatchOperateAddHeaderFooterViewController {
            if self != addHeaderFooter {
                loadData()
            }
        }
    }
    @objc func themeChanged(notification: Notification) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
            self.updateViewColor()
        }
    }
    @objc func batchFilesCountNotification(notification: Notification)  {
        let files = notification.object as? [Any]
        if files?.count ?? 0 > 0 {
            haveFiles = true
        } else {
            haveFiles = false
        }
        updateActionButtonbackgroundColor()
    }
    func loadData() {
        self.tableView.reloadData()
    }
    func updateViewColor() {
        if KMAppearance.isDarkMode() {
            self.bottomBaseView.layer?.backgroundColor = NSColor(red: 0.149, green: 0.157, blue: 0.169, alpha: 1).cgColor
            self.addButton.layer?.backgroundColor = NSColor(red: 0.337, green: 0.345, blue: 0.353, alpha: 1).cgColor
            self.addButton.setTitleColor(NSColor.white)
            self.actionButton.layer?.backgroundColor = NSColor(red: 0.306, green: 0.498, blue: 0.859, alpha: 1).cgColor
            self.actionButton.setTitleColor(KMAppearance.Layout.w0Color())
        } else {
            self.bottomBaseView.layer?.backgroundColor = NSColor(red: 0.988, green: 0.992, blue: 1.000, alpha: 1).cgColor
            self.addButton.layer?.backgroundColor = NSColor(red: 0.855, green: 0.859, blue: 0.871, alpha: 1).cgColor
            self.addButton.setTitleColor(NSColor(red: 0.055, green: 0.067, blue: 0.078, alpha: 1))
            self.actionButton.layer?.backgroundColor = NSColor(red: 0.153, green: 0.235, blue: 0.384, alpha: 1).cgColor
            self.actionButton.setTitleColor(KMAppearance.Layout.w0Color())
        }
    }
    func deleteAll() {
        if self.isBates {
            for waterMark in KMHeaderFooterManager.defaultManager.onlyBatesObjects {
                KMHeaderFooterManager.defaultManager.removeHeaderFooter(waterMark)
            }
        } else {
            for waterMark in KMHeaderFooterManager.defaultManager.onlyHeaderFooterObjects {
                KMHeaderFooterManager.defaultManager.removeHeaderFooter(waterMark)
            }
        }
        loadData()
        reloadTable()
        postNotification()
    }
    func reloadTable() {
        self.tableView.noteNumberOfRowsChanged()
        var count = 0
        var array: [KMHeaderFooterObject] = []
        if self.isBates {
            count = KMHeaderFooterManager.defaultManager.onlyBatesObjects.count
            array = KMHeaderFooterManager.defaultManager.onlyBatesObjects
        } else {
            count = KMHeaderFooterManager.defaultManager.onlyHeaderFooterObjects.count
            array = KMHeaderFooterManager.defaultManager.onlyHeaderFooterObjects
        }
        if array.contains(self.currentObject!) {
            let row = array.firstIndex(of: self.currentObject!)!
            let indexSet = IndexSet(integer: row)
            self.tableView.selectRowIndexes(indexSet, byExtendingSelection: false)
        }
        updateActionButtonbackgroundColor()
    }
    func postNotification() {
        NotificationCenter.default.post(name: NSNotification.Name("KMBatchOperateHeaderFootersNotification"), object: self)
    }
    
    @IBAction func buttonClicked_AddHeaderFooter(_ sender: Any) {
//        guard let windowController = self.view.window?.windowController else { return }
//        var filePath: String?
//        var password: String?
//        if let mainWC = windowController as? MainWindowController {
//            //            filePath = mainWC.pdfView?.document?.documentURL?.path
//            //            password = (mainWC.pdfView?.document as? CPDFDocument)?.password
//        }
//        let wc = KMHeaderFooterManagerWindowController(baseFile: filePath, headerFooter: nil, password: password, type: .KMBatchModifyTemplateType_Add)
//        wc.isBates = self.isBates
//        wc.operateCallBack = { [weak self] obj in
//            self?.currentObject = obj
//            self?.loadData()
//            self?.postNotification()
//            DispatchQueue.main.async {
//                guard let strongSelf = self else {
//                    return
//                }
//                strongSelf.tableView.selectRowIndexes(IndexSet(integer: 0), byExtendingSelection: false)
//            }
//        }
//        wc.beginSheetModal(for: NSApp.keyWindow!, completionHandler: nil)
    }
    
    @IBAction func buttonClicked_Action(_ sender: Any) {
        
    }
    func checkAndResetTask() -> Bool {
        if files?.count ?? 0 < 1 {
            return false
        }
        for i in 0..<(files?.count ?? 0) {
            if let file = files?[i] as? KMBatchOperateFile {
                if isBates {
                    file.addBatesInfo.resetState()
                } else {
                    file.addHeaderFooterInfo.resetState()
                }
            }
        }
        return true
    }
    func choosePathAndBeginOperation(_ obj: Any) {
        let openPanel = NSOpenPanel()
        openPanel.canChooseFiles = false
        openPanel.canChooseDirectories = true
        openPanel.canCreateDirectories = true
        openPanel.beginSheetModal(for: self.view.window!) { (result) in
            if result == NSApplication.ModalResponse.OK {
                for fileURL in openPanel.urls {
                    self.choosePath = fileURL.path
                    if self.isBates {
                        self.beginAddBates(obj as! KMHeaderFooterObject)
                    } else {
                        self.beginAddHeaderFooter(obj as! KMHeaderFooterObject)
                    }
                }
            }
        }
    }
    func beginAddBates(_ bates: KMHeaderFooterObject) {
        hiddenWindowCloseButtonIfNeeded()
        successFilePathURLArray?.removeAll()
        for i in 0..<(files?.count ?? 0) {
            if let file = files?[i] as? KMBatchOperateFile {
                if file.fileType == .PDF {
                    file.addBatesInfo.savePath = choosePath
                    if file.status == .Waiting {
                        let operation = KMBatchAddHeaderFooterOperation(file: file, headerFooter: bates)
                        operation.delegate = self
                        queue?.addOperation(operation)
                    }
                }
            }
        }
        if queue?.operationCount ?? 0 > 0 {
            interfaceStatus = .Processing
        }
    }
    func beginAddHeaderFooter(_ headerFooter: KMHeaderFooterObject) {
        hiddenWindowCloseButtonIfNeeded()
        successFilePathURLArray?.removeAll()
        for i in 0..<(files?.count ?? 0) {
            if let file = files?[i] as? KMBatchOperateFile {
                if file.fileType == .PDF {
                    file.addHeaderFooterInfo.savePath = choosePath
                    if file.status == .Waiting {
                        let operation = KMBatchAddHeaderFooterOperation(file: file, headerFooter: headerFooter)
                        operation.delegate = self
                        queue?.addOperation(operation)
                    }
                }
            }
        }
        if queue?.operationCount ?? 0 > 0 {
            interfaceStatus = .Processing
        }
    }
    func modify(obj: KMHeaderFooterObject) {
//        let windowController = self.view.window?.windowController
//        var filePath: String? = nil
//        var password: String? = nil
//        if let mainWindowController = windowController as? MainWindowController {
//            filePath = mainWindowController.mainViewController.listView?.document?.documentURL?.path
//            let document = mainWindowController.mainViewController.listView?.document as? CPDFDocument
//            password = document?.password
//        }
//        let wc = KMHeaderFooterManagerWindowController(baseFile: filePath, headerFooter: obj, password: password, type: .KMBatchModifyTemplateType_Edit)
//        wc?.isBates = self.isBates
//        let blockSelf = self
//        wc?.operateCallBack = { obj in
//            blockSelf.currentObject = obj
//            blockSelf.loadData()
//            blockSelf.reloadTable()
//            blockSelf.postNotification()
//        }
//        wc?.beginSheetModalForWindow(NSApp.keyWindow, completionHandler: nil)
    }
    func delete(obj: KMHeaderFooterObject) {
        KMHeaderFooterManager.defaultManager.removeHeaderFooter(obj)
        loadData()
        reloadTable()
        postNotification()
    }
    func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
        let action = menuItem.action
        if action == #selector(buttonItemClick_CleanAll(_:)) {
            if (self.isBates && KMHeaderFooterManager.defaultManager.onlyBatesObjects.count < 1) || (!self.isBates && KMHeaderFooterManager.defaultManager.onlyHeaderFooterObjects.count < 1){
                return false
            }
            return true
        }
        return true
    }
    func headerFooterInterfaceSelectHeaderFooter(headerFooter: KMHeaderFooterObject) {
        self.tableView.reloadData()
        if let index = KMHeaderFooterManager.defaultManager.onlyHeaderFooterObjects.index(of: headerFooter) {
            let indexSet = IndexSet(integer: index)
            self.tableView.selectRowIndexes(indexSet, byExtendingSelection: false)
        }
    }
    func batesInterfaceSelectBates(headerFooter: KMHeaderFooterObject) {
        self.tableView.reloadData()
        if let index = KMHeaderFooterManager.defaultManager.onlyBatesObjects.index(of: headerFooter) {
            let indexSet = IndexSet(integer: index)
            self.tableView.selectRowIndexes(indexSet, byExtendingSelection: false)
        }
    }
   
    func numberOfRows(in tableView: NSTableView) -> Int {
        var count = 0
        if self.isBates {
            count = KMHeaderFooterManager.defaultManager.onlyBatesObjects.count
        } else {
            count = KMHeaderFooterManager.defaultManager.onlyHeaderFooterObjects.count
        }
        self.blankView.isHidden = count != 0
        return count
    }
    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        var obj: KMHeaderFooterObject? = nil
        if self.isBates {
            obj = KMHeaderFooterManager.defaultManager.onlyBatesObjects[row]
        } else {
            obj = KMHeaderFooterManager.defaultManager.onlyHeaderFooterObjects[row]
        }
        guard let cellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "mainCell"), owner: self) as? KMHeaderFooterTableCellView else {
            return nil
        }
        
        cellView.updateInterface(obj!)
        cellView.headerFooterTableCellViewCallback = { type in
            if type == .Edit {
                let indexSet = IndexSet(integer: row)
                self.tableView.selectRowIndexes(indexSet, byExtendingSelection: false)
                self.currentObject = obj
                self.modify(obj: obj!)
            } else {
                self.delete(obj: obj!)
            }
        }
        return cellView
    }
    func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
        let rowView = KMTableRowView() 
        return rowView
    }
    func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { 
        if self.isBates {
            return KMHeaderFooterManager.defaultManager.onlyBatesObjects[row].cellHeight
        } else {
            return KMHeaderFooterManager.defaultManager.onlyHeaderFooterObjects[row].cellHeight
        }
    }
    func tableViewSelectionDidChange(_ notification: Notification) {
        let row = self.tableView.selectedRow
        updateActionButtonbackgroundColor()
        if row == -1 { return }
        if self.isBates {
            let bates = KMHeaderFooterManager.defaultManager.onlyBatesObjects[row]
            self.currentObject = bates
            for i in 0..<(self.files?.count ?? 0) {
                let file = self.files?[i]
                file?.addBatesInfo.pageChoice = bates.pageChoice
                if file?.addBatesInfo.pageChoice == .Input {
                    let arr = allPageNumbers(bates.pagesString)
                    let sortedArray: NSArray = file!.pagesArrayIntersect(with: arr) as NSArray
                    if sortedArray.count < 1 {
                        file?.addBatesInfo.pageChoice = .All
                    } else {
                        file!.addBatesInfo.pageRangeString = sortedArray.componentsJoined(by: ",")
                    }
                }
            }
        } else {
            let headerFooter = KMHeaderFooterManager.defaultManager.onlyHeaderFooterObjects[row]
            self.currentObject = headerFooter
            for i in 0..<(self.files?.count ?? 0) {
                let file = self.files?[i]
                file?.addHeaderFooterInfo.pageChoice = headerFooter.pageChoice
                if file?.addHeaderFooterInfo.pageChoice == .Input {
                    let arr = allPageNumbers(headerFooter.pagesString)
                    let sortedArray: NSArray = file!.pagesArrayIntersect(with: arr) as NSArray
                    if sortedArray.count < 1 {
                        file?.addHeaderFooterInfo.pageChoice = .All
                    } else {
                        file!.addHeaderFooterInfo.pageRangeString = sortedArray.componentsJoined(by: ",")
                    }
                }
            }
        }
        reloadTable()
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: kNeedChangePageRangeNotification), object: nil)
    }
}