//
//  File.swift
//  PDF Reader Pro
//
//  Created by liujiajie on 2023/11/30.
//

import Foundation

typealias compressCallbackBlock = (_ isSuccess: Bool) -> Void

class KMCompressOperation: KMBatchOperation{
    var dpiValue: NSNumber = 0
    var pdfDocument: CPDFDocument?
    init(file: KMBatchOperateFile, compressValue dpiType: NSNumber) {
        super.init(file: file)
        self.dpiValue = dpiType
       
    }
    override func start() {
        if !self.isCancelled {
            self.pdfDocument = CPDFDocument(url: URL(fileURLWithPath: self.operateFile?.filePath ?? ""))
            if let data = self.pdfDocument?.isLocked, data {
                self.pdfDocument?.unlock(withPassword: self.operateFile?.password)
            }
            self.delegate?.fileBeginOperate?(self.operateFile!, info: self.operateFile!.compressInfo)
            
            willChangeValue(forKey: "isExecuting")
            self.hasExcuting = true
            didChangeValue(forKey: "isExecuting")
            if !FileManager.default.fileExists(atPath: self.operateFile?.filePath ?? "") {
                self.delegate?.fileOperateFailed?(self.operateFile!, error: self.errorWithMsg(KMLocalizedString("File Not Exist", nil)), info: self.operateFile!.removePasswordInfo)
                
                self.willChangeValue(forKey: "isFinished")
                self.hasFinished = true
                self.didChangeValue(forKey: "isFinished")
                return
            }
            
            if self.pdfDocument == nil {
                self.delegate?.fileOperateFailed?(self.operateFile!, error: self.errorWithMsg(KMLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", nil)), info: self.operateFile!.removeWatermarkInfo)
                self.willChangeValue(forKey: "isFinished")
                self.hasFinished = true
                self.didChangeValue(forKey: "isFinished")
                return
            }
            self.compressToPath(targetPath: (self.operateFile?.compressInfo.fetchDestinationFilepath()), documentPath: self.operateFile?.filePath ?? "", password: self.operateFile?.password ?? "", compressType: self.dpiValue) { isSuccess in
                if isSuccess {
                    self.delegate?.fileOperateSuccessed?(self.operateFile!, info: self.operateFile!.compressInfo)
                }else{
                    self.delegate?.fileOperateFailed?(self.operateFile!, error: self.errorWithMsg(KMLocalizedString("Failed", nil)), info: self.operateFile!.compressInfo)
                }
            }
            DispatchQueue.main.async {
                if self.viewController?.view.window?.isVisible == true {
                    self.willChangeValue(forKey: "isFinished")
                    self.hasFinished = true
                    self.didChangeValue(forKey: "isFinished")
                }
            }
        }else {
            DispatchQueue.main.async {
                if self.viewController?.view.window?.isVisible == true {
                    self.willChangeValue(forKey: "isFinished")
                    self.willChangeValue(forKey: "isExecuting")
                    self.hasExcuting = false
                    self.hasFinished = true
                    self.didChangeValue(forKey: "isExecuting")
                    self.didChangeValue(forKey: "isFinished")
                }
            }
        }
    }
    override func cancel() {
        //        super.cancel()
        if isExecuting {
            self.operateFile?.compressInfo.status = .Waiting
            if FileManager.default.fileExists(atPath: (operateFile?.compressInfo.outPutPath)!) { try? FileManager.default.removeItem(atPath: (operateFile!.compressInfo.outPutPath)!)
            }
            self.delegate?.fileOperateCanceled?(self.operateFile!, info: self.operateFile!.compressInfo)
            DispatchQueue.main.async {
                if self.viewController?.view.window?.isVisible == true {
                    self.willChangeValue(forKey: "isFinished")
                    self.hasFinished = true
                    self.didChangeValue(forKey: "isFinished")
                }
            }
        } else {
            DispatchQueue.main.async {
                if self.viewController?.view.window?.isVisible == true {
                    self.willChangeValue(forKey: "isCancelled")
                    self.hasCanceled = true
                    self.didChangeValue(forKey: "isCancelled")
                }
            }
        }
    }
    func compressToPath(targetPath: String?, documentPath: String, password: String, compressType: NSNumber?, completeHandler: compressCallbackBlock) {
        if self.pdfDocument!.isLocked {
            let unlockSuccess = self.pdfDocument!.unlock(withPassword: password)
            if !unlockSuccess {
                completeHandler(false)
                return
            }
        }
        if compressType == nil {
            
            completeHandler(false)
            return
        }
        let isSuccessfully = self.pdfDocument!.writeOptimize(to: URL(fileURLWithPath: targetPath ?? ""), withOptions: [CPDFDocumentOptimizeOption.imageQualityOption: compressType as Any])
        completeHandler(isSuccessfully)
    }
}