//
//  KMPDFInsertPageWindow.swift
//  PDF Reader Pro
//
//  Created by wanjun on 2022/11/24.
//

import Cocoa

enum KMPDFToolType : Int {
    case Insert = 0
    case Extract
}

class KMPDFInsertPageWindow: NSWindowController {
    
    @IBOutlet weak var titleLabel: NSTextField!
    @IBOutlet weak var mainLeftBox: NSBox!
    @IBOutlet weak var mainRightBox: NSBox!
    @IBOutlet weak var okBox: KMBox!
    @IBOutlet weak var okLabel: NSTextField!
    @IBOutlet weak var cancelBox: KMBox!
    @IBOutlet weak var cancelLabel: NSTextField!
    
    @IBOutlet var insertPreviewViewController: KMPDFInsertPreviewViewController!
    @IBOutlet var insertActionViewController: KMHomeInsertActionViewController!
    @IBOutlet var extractActionViewController: KMHomeExtractActionViewController!
    
    var type: KMPDFToolType!
    var pdfDocument: CPDFDocument!
    
    var filePath: URL?
    var insertScopeType: KMInsertScopeType! = .firstPage
    var pageScopeType: KMPageScopeType! = .previous
    var password: String = ""
    var fromFilePassword: String = ""
    var insertPages: [CPDFPage] = []
    var insertPageIndex: Int = 0
    var currentPageCount: Int = 1
    
    var isOneDocumentPerPage: Bool = false
    var isDeletePage: Bool = false

    override func windowDidLoad() {
        super.windowDidLoad()

        initializeUI()
        initLocalization()
        
        cancelBox.downCallback = { [self](downEntered: Bool, mouseBox: KMBox, event) -> Void in
            if downEntered {
                cancelAction(mouseBox)
            }
        }
        
        okBox.downCallback = { [self] (downEntered: Bool, mouseBox: KMBox, event) -> Void in
            if downEntered {
                switch type {
                case .Insert:
                    insertAction(mouseBox)
                case .Extract:
                    extractAction(mouseBox)
                case .none:
                    break
                }
            }
        }
        
        insertPreviewViewController.delete = self
        insertActionViewController.delete = self
        extractActionViewController.delete = self
        reloadData()
        
        if pdfDocument.isLocked {
            
        }
    }
    
    // MARK: Init

    convenience init(documentPath: URL, toolType: KMPDFToolType) {
        self.init(windowNibName: NSNib.Name("KMPDFInsertPageWindow"))
        
        type = toolType
        pdfDocument = CPDFDocument(url: documentPath)

        switch toolType {
        case .Insert:
            self.window?.setContentSize(NSSize(width: 480, height: 441))
        case .Extract:
            self.window?.setContentSize(NSSize(width: 480, height: 404))
        }
    }
    
    func initializeUI() -> Void {
        cancelBox.fillColor = .white
        cancelLabel.textColor = .black
        okBox.fillColor = .black
        okLabel.textColor = .white
    }
    
    func initLocalization() -> Void {
        switch type {
        case .Insert:
            titleLabel.stringValue = NSLocalizedString("插入", comment: "")
            okLabel.stringValue = NSLocalizedString("插入", comment: "")
            okBox.toolTip = NSLocalizedString("插入", comment: "")
            cancelLabel.stringValue = NSLocalizedString("取消", comment: "")
            cancelBox.toolTip = NSLocalizedString("取消", comment: "")
        case .some(.Extract):
            titleLabel.stringValue = NSLocalizedString("提取", comment: "")
            okLabel.stringValue = NSLocalizedString("提取", comment: "")
            okBox.toolTip = NSLocalizedString("提取", comment: "")
            cancelLabel.stringValue = NSLocalizedString("取消", comment: "")
            cancelBox.toolTip = NSLocalizedString("取消", comment: "")
        case .none:
            break
        }
    }
    
    // MARK: private

    func reloadData() -> Void {
        switch type {
        case .Insert:
            insertPreviewViewController.pdfDocument = pdfDocument
            insertActionViewController.pdfDocument = pdfDocument
            mainLeftBox.contentView = insertPreviewViewController.view
            mainRightBox.contentView = insertActionViewController.view
        case .Extract:
            insertPreviewViewController.pdfDocument = pdfDocument
            extractActionViewController.pdfDocument = pdfDocument
            mainLeftBox.contentView = insertPreviewViewController.view
            mainRightBox.contentView = extractActionViewController.view
        default:
            break
        }
    }
    
    func beginSheetModal(for window: NSWindow, completionHandler handler: ((_ pdfDocument: CPDFDocument, _ password: String, _ pages: [CPDFPage], _ indexPage: Int) -> Void)?) {
        window.beginSheet(self.window!) { [self] returnCode in
            if pdfDocument != nil {
                handler!(pdfDocument!, password, insertPages, insertPageIndex)
            }
        }
    }

    func beginSheetExtractModal(for window: NSWindow, completionHandler handler: ((_ pdfDocument: CPDFDocument, _ pages: [CPDFPage], _ oneDocumentPerPage: Bool, _ isDeletePage: Bool) -> Void)?) {
        window.beginSheet(self.window!) { [self] returnCode in
            if pdfDocument != nil {
                handler!(pdfDocument!, insertPages, isOneDocumentPerPage, isDeletePage)
            }
        }
    }
    
    // MARK: Action

    @IBAction func cancelAction(_ sender: Any) -> Void {
        pdfDocument = nil
        NSApp.mainWindow!.endSheet(self.window!)
        self.window?.orderOut(self)
    }
    
    @IBAction func insertAction(_ sender: Any) -> Void {
        if filePath?.path == "" {
            let alert = NSAlert()
            alert.alertStyle = .critical
            alert.messageText = NSLocalizedString("Select a File", comment:  "")
            alert.runModal()
            return
        }
        
        if pdfDocument.isLocked {
            pdfDocument.unlock(withPassword: password)
        }
        
        let fromDocument = CPDFDocument(url: filePath)!
        if fromDocument.isLocked {
            fromDocument.unlock(withPassword: fromFilePassword)
        }
        
        var pages: [CPDFPage] = []
        let insertPDF = CPDFDocument(url: filePath)
        for count in 1...insertPDF!.pageCount {
            let page = insertPDF?.page(at: UInt(count - 1))
            pages.append(page!)
        }
        
        var index = 0
        switch insertScopeType {
        case .firstPage:
            index = 0
        case .lastPage:
            index = Int(pdfDocument.pageCount)
        case .customizePage:
            index = currentPageCount
            if 1 == pageScopeType.rawValue {
                index = index - 1
            }
        case .none:
            index = 0
        }
        
        insertPages = pages
        insertPageIndex = index
        
        NSApp.mainWindow!.endSheet(self.window!)
        self.window?.orderOut(self)
    }
    
    @IBAction func extractAction(_ sender: Any) -> Void {
        NSApp.mainWindow!.endSheet(self.window!)
        self.window?.orderOut(self)
    }
}

// MARK: - KMPDFInsertPreviewViewControllerDelegate

extension KMPDFInsertPageWindow: KMPDFInsertPreviewViewControllerDelegate {
    func insertPreviewViewController(_ viewController: KMPDFInsertPreviewViewController, pageChanged: Int) {
        switch type {
        case .Insert:
            insertActionViewController.currentPageCount = pageChanged
            insertActionViewController.reloadData()
        case .Extract:
            extractActionViewController.currentPageCount = pageChanged
            extractActionViewController.reloadData()
        default:
            break
        }
    }
}

// MARK: - KMHomeInsertActionViewControllerDelegate

extension KMPDFInsertPageWindow: KMHomeInsertActionViewControllerDelegate {
    func insertActionViewController(_ viewController: KMHomeInsertActionViewController, fromFilePath: URL) {
        self.filePath = fromFilePath
    }
    
    func insertActionViewController(_ viewController: KMHomeInsertActionViewController, insertScopeType: KMInsertScopeType, currentPage: Int, pageScope: KMPageScopeType) {
        self.insertScopeType = insertScopeType
        self.currentPageCount = currentPage
        self.pageScopeType = pageScope
    }
}

// MARK: KMHomeExtractActionViewControllerDelegate

extension KMPDFInsertPageWindow: KMHomeExtractActionViewControllerDelegate {
    func extractActionViewController(_ viewController: KMHomeExtractActionViewController, pages: [CPDFPage]) {
        self.insertPages = pages
    }
    
    func extractActionViewController(_ viewController: KMHomeExtractActionViewController, isOneDocumentPerPage: Bool, isDeletePage: Bool) {
        self.isOneDocumentPerPage = isOneDocumentPerPage
        self.isDeletePage = isDeletePage
    }
}