//
//  KMMergeView.swift
//  PDF Master
//
//  Created by lizhe on 2023/11/8.
//

import Cocoa

typealias KMMergeViewCancelAction = (_ view: KMMergeView) -> Void
typealias KMMergeViewAddFilesAction = (_ view: KMMergeView) -> Void
typealias KMMergeViewMergeAction = (_ view: KMMergeView) -> Void
typealias KMMergeViewClearAction = (_ view: KMMergeView) -> Void

class KMMergeView: KMBaseXibView {
    @IBOutlet weak var tableview: NSTableView!
    
    @IBOutlet weak var clearButton: NSButton!
    
    @IBOutlet weak var cancelButton: NSButton!
    @IBOutlet weak var mergeButton: NSButton!
    @IBOutlet weak var addFilesButton: NSButton!
    
    @IBOutlet weak var progress: NSProgressIndicator!
    
    @IBOutlet weak var pageSizeWidthTextField: NSTextField!
    @IBOutlet weak var pageSizeWidthHeightConnectorTextField: NSTextField!
    @IBOutlet weak var pageSizeHeightTextField: NSTextField!
    @IBOutlet weak var pageSizeUnitLabel: NSTextField!
    
    @IBOutlet weak var originalSizeButton: NSButton!
    @IBOutlet weak var A4SizeButton: NSButton!
    @IBOutlet weak var A3SizeButton: NSButton!
    @IBOutlet weak var USLetterSizeButton: NSButton!
    @IBOutlet weak var USLegalButton: NSButton!
    @IBOutlet weak var customSizeButton: NSButton!
    @IBOutlet weak var box: KMBox!
    @IBOutlet weak var boxLabel: NSTextField!
    
    @IBOutlet weak var blankView: KMMergeBlankView!
    
    var cancelAction: KMMergeViewCancelAction?
    var addFilesAction: KMMergeViewAddFilesAction?
    var mergeAction: KMMergeViewMergeAction?
    var clearAction: KMMergeViewClearAction?
    
    
    let MyTableCellViewDataType = NSPasteboard.PasteboardType(rawValue: "KMLocalForDraggedTypes")
    var files: [KMFileAttribute] = [] //导入文件
    var lockFiles: [KMFileAttribute] = [] //存在密码文件
    var lockFilesIndex: Int = 0
    var newPageSize = CGSizeZero
    
    var insertRow: Int = 0
    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // Drawing code here.
    }
    
    override func setup() {
        self.box.cornerRadius = 4
        
        pageSizeWidthTextField.isEnabled = false
        pageSizeHeightTextField.isEnabled = false;
        
        tableview.delegate = self
        tableview.dataSource = self
        tableview.allowsMultipleSelection = true
        
//        tableview.register(NSNib.init(nibNamed: "KMMergeTableViewCell", bundle: nil), forIdentifier: NSUserInterfaceItemIdentifier(rawValue: "KMMergeTableViewCell"))
        
        progress.isHidden = true
        
        boxLabel.textColor = KMAppearance.Layout.h0Color()
        
        blankView.dragAction = { [unowned self] view, filePaths in
            self.addFilePaths(urls: filePaths)
        }
    }
    
    override func updateLanguage() {
            
        originalSizeButton.title = NSLocalizedString("Original Size", comment: "")
        A4SizeButton.title = "A4";
        A3SizeButton.title = "A3";
        USLetterSizeButton.title = NSLocalizedString("U.S.Letter", comment: "");
        USLegalButton.title = NSLocalizedString("U.S.Legal", comment: "");
        customSizeButton.title = NSLocalizedString("Custom",  comment: "");
        pageSizeWidthTextField.stringValue = "595";
        pageSizeHeightTextField.stringValue = "841";
        
        cancelButton.title = NSLocalizedString("Cancel",  comment: "");
        clearButton.title = NSLocalizedString("Clear",  comment: "");
        addFilesButton.title = NSLocalizedString("Add Files",  comment: "")
        mergeButton.title = NSLocalizedString("Merge",  comment: "")
        
        boxLabel.stringValue = NSLocalizedString("Page size:", comment: "")
    }
    
    override func reloadData() {
        self.updateButtonState()
        if files.count != 0 {
            self.blankView.isHidden = true
        } else {
            self.blankView.isHidden = false
        }
        
        self.tableview.reloadData()
    }
    
    func updateButtonState() {
        if (files.count > 0) {
            blankView.isHidden = true
            clearButton.isEnabled = true
            mergeButton.isEnabled = true
        } else {
            blankView.isHidden = false
            clearButton.isEnabled = false
            mergeButton.isEnabled = false
        }
    }
}

extension KMMergeView {
    func controlTextDidChange(_ obj: Notification) {
//        NSTextField *textField = (NSTextField*)[obj object];
//        NSInteger index = textField.tag;
//        [[_files objectAtIndex:index] setPagesString:textField.stringValue];
    }
}

extension KMMergeView: NSTableViewDataSource {
    func numberOfRows(in tableView: NSTableView) -> Int {
        return files.count
    }
    
    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        if let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("KMMergeTableViewCell"), owner: nil) as? KMMergeTableViewCell {
            // 配置单元格的显示内容
            cell.removeAction = { [unowned self] view, model in
                self.files.removeObject(model)
                self.reloadData()
            }
            return cell
        }
        return nil
    }
    
    func tableView(_ tableView: NSTableView, shouldSelect tableColumn: NSTableColumn?) -> Bool {
        return false
    }
    
    func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
        return 60
    }
}

extension KMMergeView: NSTableViewDelegate {
    func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
        let indexSetData = try? NSKeyedArchiver.archivedData(withRootObject: rowIndexes, requiringSecureCoding: true)
        pboard.declareTypes([NSPasteboard.PasteboardType.string], owner: self)
        pboard.setData(indexSetData, forType: MyTableCellViewDataType)
        return true
    }
    
    func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
        if dropOperation == .on {
            return []
        }

        var isCanDrag = false
        var result = NSDragOperation.copy
        let pboard = info.draggingPasteboard

        if pboard.availableType(from: [NSPasteboard.PasteboardType.fileNameType(forPathExtension: "pdf")]) != nil {
            if let fileNames = pboard.propertyList(forType: NSPasteboard.PasteboardType.fileNameType(forPathExtension: "pdf")) as? [String] {
                for path in fileNames {
                    if path.lowercased().hasSuffix("pdf") {
                        isCanDrag = true
                    } else {
                        isCanDrag = false
                        break
                    }
                }
            }
        } else if (pboard.availableType(from: [MyTableCellViewDataType]) != nil) {
            result = .every
        }

        if isCanDrag {
            result = .copy
        }

        return result
    }
    
    func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
        var result = false
           let pboard = info.draggingPasteboard
           insertRow = row

//        NSPasteboard.PasteboardType.fileURL
           if pboard.availableType(from: [NSPasteboard.PasteboardType.fileNameType(forPathExtension: "pdf")]) != nil {
               if let fileNames = pboard.propertyList(forType: NSPasteboard.PasteboardType.fileNameType(forPathExtension: "pdf")) as? [String] {
                   var array = [URL]()

                   for path in fileNames {
                       if !isExistAtFilePath(filePath: path) {
                           continue
                       }
//                       if let attrib = try? FileManager.default.attributesOfItem(atPath: path),
//                          let fileSize = attrib[.size] as? CGFloat {
//
//                           allFileSize += fileSize
//
//                           if !IAPProductsManager.defaultManager.isAvailableAllFunction {
//                               // 免费版只支持2个文件做合并,小于20M的文件合并
//                               if files.count >= 2 || allFileSize > (20 * 1024 * 1024) {
//                                   let vc = KMToolCompareWindowController.toolCompare(with: .pageEdit, setSelectIndex: 1)
//                                   vc.showWindow(nil)
//
//                                   allFileSize -= fileSize
//                                   addFiles(array)
//                                   result = true
//                                   return false
//                               }
//                           }
                       array.append(URL(string: path)!)
//                       }
                   }
                   addFilePaths(urls: array)
                   result = true
               }
           } else if pboard.availableType(from: [MyTableCellViewDataType]) != nil {
               if let rowData = pboard.data(forType: MyTableCellViewDataType),
                  let rowIndexes = NSKeyedUnarchiver.unarchiveObject(with: rowData) as? IndexSet {

                   var moveArray = [KMFileAttribute]()
                   var allPhoto: [KMFileAttribute] = []
                   var index = 0
                   
                   for file in files {
                       allPhoto.append(file)
                   }

                   rowIndexes.enumerated().forEach { (idx, shouldStop) in
                       moveArray.append(allPhoto[idx])
                       files.remove(at: idx)
                   }

                   var newRow = row
                   if newRow > 0 {
                       var indexFile: KMFileAttribute?

                       repeat {
                           newRow = newRow - 1

                           guard newRow >= 0 else {
                               indexFile = nil
                               break
                           }

                           indexFile = allPhoto[row]
                       } while moveArray.contains(indexFile!)

                       if let indexFile = indexFile {
                           index = files.firstIndex(of: indexFile)! + 1
                       }
                   }

                   moveArray.enumerated().forEach { (i, file) in
                       files.insert(file, at: (index + i))
                   }

                   tableView.reloadData()
                   result = true
               }
           } else {
               result = false
           }

           return result
    }
}

extension KMMergeView {
    @IBAction func clearButtonAction(_ sender: Any) {
        self.files.removeAll()
        self.reloadData()
        
        guard let callBack = clearAction else { return }
        
        callBack(self)
    }
    
    @IBAction func cancelButtonAction(_ sender: Any) {
        guard let callBack = cancelAction else { return }
        
        callBack(self)
    }
    
    @IBAction func mergeButtonAction(_ sender: Any) {
        guard let callBack = mergeAction else { return }
        
        callBack(self)
    }
    
    @IBAction func addFilesButtonAction(_ sender: Any) {
        guard let callBack = addFilesAction else { return }
        
        callBack(self)
    }
    
    @IBAction func sizeButtonAction(_ sender: NSButton) {
        originalSizeButton.state = .off
        A3SizeButton.state = .off
        A4SizeButton.state = .off
        USLetterSizeButton.state = .off
        USLegalButton.state = .off
        customSizeButton.state = .off
        sender.state = .on
        
        pageSizeHeightTextField.isEnabled = sender.isEqual(customSizeButton)
        pageSizeWidthTextField.isEnabled = sender.isEqual(customSizeButton)
        
        var size = CGSizeZero
        switch sender.tag {
        case 0:
            break
        case 1:
            size = CGSizeMake(595, 841);
            break;
        case 2:
            size = CGSizeMake(841, 1190);
            break;
        case 3:
            size = CGSizeMake(612, 792);
            break;
        case 4:
            size = CGSizeMake(612, 1108);
            break;
        case 5:
            size = CGSizeMake(595, 841);
            pageSizeWidthTextField.stringValue = size.width.description
            pageSizeHeightTextField.stringValue = size.height.description
            break;
        default:
            break
        }
        self.newPageSize = size
    }
}

//MARK: public
extension KMMergeView {
    func addFilePaths(urls: [URL]) {
        lockFiles.removeAll()
        files.removeAll()
        
        for url in urls {
            let file = KMFileAttribute()
            file.filePath = url.path
            
            if file.isLocked {
                lockFiles.append(file)
            } else {
                files.append(file)
            }
        }
        
        lockFilesIndex = 0
        self.openPasswordFile { success, resultPassword in
            self.reloadData()
        }
    }
    
    func openPasswordFile(completion: @escaping ((_ success: Bool, _ resultPassword: String) -> Void)) {
        if lockFiles.count != 0 {
            let file = lockFiles[lockFilesIndex]
            KMBaseWindowController.checkPassword(url: URL(string: file.filePath)!) { [unowned self] success, resultPassword in
                if success {
                    file.password = resultPassword
                    lockFilesIndex = lockFilesIndex + 1
                    
                    if lockFiles.count > lockFilesIndex {
                        self.openPasswordFile(completion: completion)
                    }
                } else {
                    completion(false, "")
                }
                
            }
        } else {
            completion(true, "")
        }
    }
}

//MARK: private
extension KMMergeView {
    private func openFilePath(url: URL) {
        NSWorkspace.shared.activateFileViewerSelecting([url])
    }
    
    private func isExistAtFilePath(filePath: String) -> Bool{
        for file in self.files {
            if file.filePath == filePath {
                return true
            }
        }
        
        return false
    }
}