//
//  KMAITranslationVC.swift
//  PDF Master
//
//  Created by wanjun on 2023/5/22.
//

import Cocoa

class KMAITranslationVC: NSViewController {

    @IBOutlet weak var aiTranslationLabel: NSTextField!
    @IBOutlet weak var aiTranslationView: KMDottedLineView!
    @IBOutlet weak var supportPDFWordFileImageView: NSImageView!
    @IBOutlet weak var supportPDFWordFileLabel: NSTextField!
    @IBOutlet weak var supportPDFWordFileSubLabel: NSTextField!
    @IBOutlet weak var translationLanguageLabel: NSTextField!
    @IBOutlet weak var automaticBox: KMBox!
    @IBOutlet weak var automaticLabel: NSTextField!
    @IBOutlet weak var languageBox: KMBox!
    @IBOutlet weak var languageLabel: NSTextField!
    @IBOutlet weak var languageImageView: NSImageView!
    @IBOutlet weak var selectYourFilesBox: KMBox!
    @IBOutlet weak var selectYourFilesLabel: NSTextField!
    @IBOutlet weak var selectYourFilesImageView: NSImageView!
    @IBOutlet weak var orDropFileHereLabel: NSTextField!
    
    @IBOutlet weak var errorView: NSView!
    @IBOutlet weak var errorLabel: NSTextField!
    
    var fromStr: String = "auto"
    var toStr: String = "en"
    var fromLanguages: [String] = ["Automatic", "English", "Simplified Chinese", "Traditional Chinese", "Japanese", "Korean", "French", "Spanish", "Italian", "German", "Portuguese", "Russian", "Vietnamese", "Thai", "Arabic", "Greek", "Bulgarian", "Finnish", "Slovene", "Dutch", "Czech", "Swedish", "Polish", "Danish", "Romanian", "Hungarian"]
    var toLanguages: [String] = ["English", "Simplified Chinese", "Traditional Chinese", "Japanese", "Korean", "French", "Spanish", "Italian", "German", "Portuguese", "Russian", "Vietnamese", "Thai", "Arabic", "Greek", "Bulgarian", "Finnish", "Slovene", "Dutch", "Czech", "Swedish", "Polish", "Danish", "Romanian", "Hungarian"]

    var popover: NSPopover?
    var progressController: SKProgressController?
    var timer: Timer?
    var timerCounter = 0.0

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        
        self.initLocalization()
        self.initializeUI()
    }
    
    override func viewDidAppear() {
        super.viewDidAppear()
        
        self.errorView.isHidden = true
        
        self.initLocalization()
    }
    
    // MARK: initialize
    
    func initializeUI() -> Void {
        self.aiTranslationView.canHover = false

        self.aiTranslationLabel.textColor = NSColor.km_init(hex: "#252629")
        self.aiTranslationLabel.font = NSFont.SFProTextSemiboldFont(20.0)
        
        self.supportPDFWordFileImageView.image = NSImage(named: "ic_function_other")
        self.supportPDFWordFileLabel.textColor = NSColor.km_init(hex: "#252629")
        self.supportPDFWordFileLabel.font = NSFont.SFProTextSemiboldFont(20.0)
        self.supportPDFWordFileSubLabel.textColor = NSColor.km_init(hex: "#94989C")
        self.supportPDFWordFileSubLabel.font = NSFont.SFProTextRegularFont(14.0)

        self.translationLanguageLabel.textColor = NSColor.km_init(hex: "#252629")
        self.translationLanguageLabel.font = NSFont.SFProTextRegularFont(14.0)
        self.automaticLabel.textColor = NSColor.km_init(hex: "#252629")
        self.automaticLabel.font = NSFont.SFProTextRegularFont(16.0)
        self.languageLabel.textColor = NSColor.km_init(hex: "#252629")
        self.languageLabel.font = NSFont.SFProTextRegularFont(16.0)
        self.automaticBox.cornerRadius = 4.0
        self.automaticBox.borderColor = NSColor.km_init(hex: "#DFE1E5")
        self.languageBox.cornerRadius = 4.0
        self.languageBox.borderColor = NSColor.km_init(hex: "#DFE1E5")
        self.languageImageView.image = NSImage(named: "ic_transtate")
        self.automaticBox.downCallback = { [unowned self](downEntered: Bool, mouseBox: KMBox, event) -> Void in
            if downEntered {
                self.languageAction(true)
            }
        }
        self.languageBox.downCallback = { [unowned self](downEntered: Bool, mouseBox: KMBox, event) -> Void in
            if downEntered {
                self.languageAction(false)
            }
        }

        self.selectYourFilesBox.cornerRadius = 4.0
        self.selectYourFilesBox.fillColor = NSColor.km_init(hex: "#1770F4")
        self.selectYourFilesLabel.textColor = NSColor.km_init(hex: "#FFFFFF")
        self.selectYourFilesLabel.font = NSFont.SFProTextRegularFont(16.0)
        self.selectYourFilesImageView.image = NSImage(named: "icon_SelectYourFiles")
        
        self.orDropFileHereLabel.textColor = NSColor.km_init(hex: "#616469")
        self.orDropFileHereLabel.font = NSFont.SFProTextRegularFont(14.0)
        
        self.selectYourFilesBox.moveCallback = { [unowned self](mouseEntered: Bool, mouseBox: KMBox) -> Void in
            if mouseEntered {
                self.selectYourFilesBox.fillColor = NSColor.km_init(hex: "#3F8FF6")
            } else {
                self.selectYourFilesBox.fillColor = NSColor.km_init(hex: "#1770F4")
            }
        }
        self.selectYourFilesBox.downCallback = { [unowned self](downEntered: Bool, mouseBox: KMBox, event) -> Void in
            if downEntered {
                if !KMLightMemberManager.manager.isLogin() {
                    KMLoginWindowController.show(window: NSApp.mainWindow!)

                    return
                }
                self._selectFiles()
//                Task { @MainActor in
//                    if await (KMLightMemberManager.manager.canPayFunction() == false) {
//                        let _ = KMSubscribeWaterMarkWindowController.show(window: self.view.window!, type: .aiTranslate) { isSub, _, isClose in
//                            if (isClose) {
//                                return
//                            }
//                            if (isSub) {
//                                self._selectFiles()
//                                return
//                            }
//                        }
//                        return
//                    }
//                    self._selectFiles()
//                }
            }
        }
        
        self.errorView.isHidden = true
        self.errorView.wantsLayer = true
        self.errorView.layer?.backgroundColor = NSColor.km_init(hex: "##36383B").cgColor
        self.errorView.layer?.cornerRadius = 4.0
        self.errorLabel.textColor = NSColor.km_init(hex: "#FFFFFF")
        self.errorLabel.font = NSFont.SFProTextRegularFont(14.0)
    }
    
    private func _selectFiles() {
        self.errorView.isHidden = true
        
        let openPanel = NSOpenPanel()
        openPanel.allowedFileTypes = ["pdf", "PDF", "docx", "doc"]
        openPanel.allowsMultipleSelection = false
        openPanel.beginSheetModal(for: self.view.window!) { result in
            if result == .OK {
                for url in openPanel.urls {
                    let isExceedsLimit = self.isPDFPageCountExceedsLimit(filePath: url.path)
                    if (url.pathExtension == "pdf") || url.pathExtension == "PDF" {
                        if !url.path.isPDFValid() {
                            let alert = NSAlert()
                            alert.alertStyle = .critical
                            alert.messageText = NSLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.", comment: "")
                            alert.runModal()
                            return
                        }
                    }
                    if self.isFileGreaterThan10MB(atPath: url.path) {
                        self.errorView.isHidden = false
                        self.errorLabel.stringValue = NSLocalizedString("The uploaded file size cannot exceed 10MB", comment: "")
                    } else if isExceedsLimit  {
                        self.errorView.isHidden = false
                        self.errorLabel.stringValue = NSLocalizedString("Documents cannot exceed 30 pages", comment: "")
                    } else {
                        DispatchQueue.main.async {
                            self.showProgressWindow()
                            self.progressController?.maxValue = Double(100)
                        }
                        
                        self.timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.timerTick), userInfo: nil, repeats: true)
                        
                        let infoDictionary = Bundle .main.infoDictionary!
                        let majorVersion = infoDictionary["CFBundleShortVersionString"]

                        let languages = [self.automaticLabel.stringValue, self.languageLabel.stringValue]
                        UserDefaults.standard.set(languages, forKey: "KMAITranslationLanguageArrayKey")
                        UserDefaults.standard.synchronize()
                        self.fromStr = self.languageAbbreviation(self.automaticLabel.stringValue)
                        self.toStr = self.languageAbbreviation(self.languageLabel.stringValue)
                        
                        
                        let alert = NSAlert()
                        alert.messageText = NSLocalizedString("Processing times may be longer for larger documents. Thank you for your patience.", comment: "")
                        alert.addButton(withTitle: NSLocalizedString("Continue", comment: ""))
                        alert.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
                        alert.beginSheetModal(for: self.view.window!) { [unowned self] result in
                            if (result == .alertFirstButtonReturn) {
                                KMRequestServerManager.manager.aiTranslationFileUpload(file: url.path, version: majorVersion as! String) { [unowned self] success, result in
        //                                    self.hiddenProgressWindow()
                                    if success {
                                        let result: NSDictionary = result!.result

                                        let fileKey = result["fileKey"]
                                        let fileName = result["fileName"]
                                        let pageCount = result["pageCount"]
                                        if fileKey != nil {
                                            self.fileTranslateHandle(fileKey as! String)
                                        }
                                    } else {
                                        let result: String = result!.message

                                        DispatchQueue.main.async {
                                            self.hiddenProgressWindow()
                                            self.errorView.isHidden = false
                                            self.errorLabel.stringValue = result
                                        }
                                    }
                                }
                            } else if result == .alertSecondButtonReturn {
                                DispatchQueue.main.async {
                                    self.hiddenProgressWindow()
                                }
                                return
                            }
                        }
                    }
                }
            }
        }
    }
    
    func initLocalization() -> Void {
        self.aiTranslationLabel.stringValue = NSLocalizedString("AI Translation", comment: "")
        self.supportPDFWordFileLabel.stringValue = NSLocalizedString("Support PDF and Word file", comment: "")
        self.supportPDFWordFileSubLabel.stringValue = NSLocalizedString("Limit document size to 10M, document page number to 30, 10w characters per month.", comment: "")
        self.translationLanguageLabel.stringValue = NSLocalizedString("Translation Language:", comment: "")
        self.selectYourFilesLabel.stringValue = NSLocalizedString("Select your file", comment: "")
        self.orDropFileHereLabel.stringValue = NSLocalizedString("or drop file here", comment: "")
        
        let languageArr = UserDefaults.standard.array(forKey: "KMAITranslationLanguageArrayKey") as? [String] ?? []
        if (languageArr.count > 0) {
            self.automaticLabel.stringValue = languageArr[0]
            self.languageLabel.stringValue = languageArr[1]
        } else {
            self.automaticLabel.stringValue = NSLocalizedString("Automatic", comment: "")
            self.languageLabel.stringValue = NSLocalizedString("English", comment: "")

            let languages = [NSLocalizedString("Automatic", comment: ""), NSLocalizedString("English", comment: "")]
            UserDefaults.standard.set(languages, forKey: "KMAITranslationLanguageArrayKey")
            UserDefaults.standard.synchronize()
        }
    }
    
    // MARK: Private Methods
    
    func fileTranslateHandle(_ fileKey: String) -> Void {
        let infoDictionary = Bundle .main.infoDictionary!
        let majorVersion = infoDictionary["CFBundleShortVersionString"]
//        DispatchQueue.main.async {
//            self.showProgressWindow()
//        }
        
        KMRequestServerManager.manager.aiTranslationFileTranslateHandle(fileKey: fileKey, from: self.fromStr, to: self.toStr, version: majorVersion as! String) { success, result in
            if success {
                let result: NSDictionary = result!.result

                let fileUrl: String = result["fileUrl"] as! String
                let downFileUrl: String = result["downFileUrl"] as! String
                let ossDownUrl: String = result["ossDownUrl"] as! String
                let fileName: String = result["fileName"] as! String
                let downFileName: String = result["downFileName"] as! String
                let from: String = result["from"] as! String
                let to: String = result["to"] as! String
                
                self.downloadFile(filePath: ossDownUrl, downFileName: downFileName)
            } else {
                let result: String = result!.message

                DispatchQueue.main.async {
                    self.hiddenProgressWindow()
                    
                    self.errorView.isHidden = false
                    self.errorLabel.stringValue = result
                }
            }
        }
    }
    
    func downloadFile(filePath: String, downFileName: String) -> Void {
        guard let fileURL = URL(string: filePath) else {
            let alert = NSAlert()
            alert.alertStyle = .critical
            alert.messageText = NSLocalizedString("Invalid file link", comment: "")
            alert.runModal()

            return
        }
        let destinationURL = FileManager.default.temporaryDirectory.appendingPathComponent(downFileName)
        if FileManager.default.fileExists(atPath: destinationURL.path) {
            do {
                try FileManager.default.removeItem(at: destinationURL)
                KMPrint("删除旧文件成功")
            } catch {
                KMPrint("删除旧文件失败:\(error)")
            }
        }
        let sessionConfiguration = URLSessionConfiguration.default
        let session = URLSession(configuration: sessionConfiguration)
        let downloadTask = session.downloadTask(with: fileURL) { (tempLocalURL, response, error) in
            if let error = error {
                let alert = NSAlert()
                alert.alertStyle = .critical
                alert.messageText = String(format: "%@:\(error)", NSLocalizedString("Download failed", comment: ""))
                alert.runModal()
                
                return
            }

            guard let tempLocalURL = tempLocalURL else {
                let alert = NSAlert()
                alert.alertStyle = .critical
                alert.messageText = NSLocalizedString("Invalid temporary directory", comment: "")
                alert.runModal()

                return
            }
            
            DispatchQueue.main.async {
                self.hiddenProgressWindow()
            }
            
            do {
                try FileManager.default.moveItem(at: tempLocalURL, to: destinationURL)

                NSDocumentController.shared.openDocument(withContentsOf: destinationURL, display: true) { document, documentWasAlreadyOpen, error in
                    if error != nil {
                        NSApp.presentError(error!)
                    } else {
                        
                    }
                }
            } catch {
                let alert = NSAlert()
                alert.alertStyle = .critical
                alert.messageText = String(format: "%@:\(error)", NSLocalizedString("Failed to save file", comment: ""))
                alert.runModal()
            }
        }
        downloadTask.resume()
    }
    
    func languageAbbreviation(_ language: String) -> String {
        if language == "Automatic Identification" {
            return "auto"
        } else if language == "English" {
            return "en"
        } else if language == "Simplified Chinese" {
            return "zh"
        } else if language == "Traditional Chinese" {
            return "cht"
        } else if language == "Japanese" {
            return "jp"
        } else if language == "Korean" {
            return "kor"
        } else if language == "French" {
            return "fra"
        } else if language == "Spanish" {
            return "spa"
        } else if language == "Italian" {
            return "it"
        } else if language == "German" {
            return "de"
        } else if language == "Portuguese" {
            return "pt"
        } else if language == "Russian" {
            return "ru"
        } else if language == "Vietnamese" {
            return "vie"
        } else if language == "Thai" {
            return "th"
        } else if language == "Arabic" {
            return "ara"
        } else if language == "Greek" {
            return "el"
        } else if language == "Bulgarian" {
            return "bul"
        } else if language == "Finnish" {
            return "fin"
        } else if language == "Slovene" {
            return "slo"
        } else if language == "Dutch" {
            return "nl"
        } else if language == "Czech" {
            return "cs"
        } else if language == "Swedish" {
            return "swe"
        } else if language == "Polish" {
            return "pl"
        } else if language == "Danish" {
            return "dan"
        } else if language == "Romanian" {
            return "rom"
        } else if language == "Hungarian" {
            return "hu"
        }
        return "auto"
    }
    
    func showProgressWindow() {
        let progress = SKProgressController()
        progress.window?.backgroundColor = NSColor.km_init(hex: "#36383B")
        progress.window?.contentView?.wantsLayer = true
        progress.window?.contentView?.layer?.backgroundColor = NSColor.km_init(hex: "#36383B").cgColor
        progress.progressField.textColor = NSColor.white
        progress.message = NSLocalizedString("Translating...", comment: "")

        progress.closeBlock = { [unowned self] in
            
        }
        
        self.progressController = progress
        self.view.window?.beginSheet(progress.window!)
    }
    
    func hiddenProgressWindow() {
        DispatchQueue.main.async {
            self.progressController?.doubleValue = 100.0
        }
        self.stopTimer()
        
        if (self.progressController != nil) {
            self.view.window?.endSheet((self.progressController?.window)!)
            self.progressController = nil
        }
    }
    
    func isFileGreaterThan10MB(atPath filePath: String) -> Bool {
        let fileManager = FileManager.default

        do {
            let fileAttributes = try fileManager.attributesOfItem(atPath: filePath)
            if let fileSize = fileAttributes[.size] as? UInt64 {
                let megabyteSize = fileSize / (1024 * 1024)
                return megabyteSize >= 10
            }
        } catch {
            KMPrint("Error: \(error)")
        }

        return false
    }
    
    func isPDFPageCountExceedsLimit(filePath: String) -> Bool {
        let url = URL(fileURLWithPath: filePath)
        guard let document = PDFDocument(url: url) else {
            return false
        }
        
        let pageCount = document.pageCount
        return pageCount > 30
    }
    
    @objc func timerTick() {
        timerCounter += 1.0
        self.progressController?.increment(by: 1.0)
        
        if timerCounter >= 95 {
            stopTimer()
        }
    }
    
    func stopTimer() {
        timer?.invalidate()
        timer = nil
    }

    // MARK: Action Methods
    
    func languageAction(_ isFromLanguage: Bool) -> Void {
        if (self.popover != nil && self.popover!.isShown) {
            self.popover?.close()
            self.popover = nil
            return
        }
        var languages = self.fromLanguages
        if !isFromLanguage {
            languages = self.toLanguages
        }
        let vc: KMAILanguagePopVC = KMAILanguagePopVC().initWithPopViewDataArr(languages)
        let createFilePopover: NSPopover = NSPopover.init()
        self.popover = createFilePopover
        createFilePopover.contentViewController = vc
        createFilePopover.animates = true
        createFilePopover.behavior = .semitransient
        createFilePopover.setValue(true, forKey: "shouldHideAnchor")
        if isFromLanguage {
            vc.selectString = self.automaticLabel.stringValue
        } else {
            vc.selectString = self.languageLabel.stringValue
        }

        vc.downCallback = { [unowned self] (language: String) -> Void in
            createFilePopover.close()
            if isFromLanguage {
                self.automaticLabel.stringValue = language
                self.fromStr = self.languageAbbreviation(language)
            } else {
                self.languageLabel.stringValue = language
                self.toStr = self.languageAbbreviation(language)
            }
        }

        if isFromLanguage {
            createFilePopover.show(relativeTo: CGRect(x: automaticBox.bounds.origin.x, y: 10, width: automaticBox.bounds.size.width, height: automaticBox.bounds.size.height), of: automaticBox, preferredEdge: .maxY)
            
            vc.customBoxWidthLayoutConstraint.constant = automaticBox.frame.width
        } else {
            createFilePopover.show(relativeTo: CGRect(x: languageBox.bounds.origin.x, y: 10, width: languageBox.bounds.size.width, height: languageBox.bounds.size.height), of: languageBox, preferredEdge: .maxY)
            
            vc.customBoxWidthLayoutConstraint.constant = languageBox.frame.width
        }
    }
}