//
//  PDESCViewController.swift
//  PrinterDemo
//
//  Created by ios on 2019/10/28.
//  Copyright © 2019 XiamenHY. All rights reserved.
//

import UIKit
import PrinterSDK
import SVProgressHUD
import PrinterSDK

class PDESCViewController: PDBaseViewController {
    
    lazy var tableView : UITableView = {
        let temp = UITableView.init(frame: .zero, style: .plain)
        temp.delegate = self
        temp.dataSource = self
        temp.backgroundColor = .white
        temp.rowHeight = 50.0
        temp.showsVerticalScrollIndicator = false
        temp.separatorStyle = UITableViewCell.SeparatorStyle.singleLine
        return temp
    }()
    
    private var functions = [PDSettingItem]()
    var selectDocumentType = PDDocumentPickerView.commandDocument
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        navigationItem.title = "ESC function".localized
        
        view.addSubview(tableView)
        tableView.snp.makeConstraints {
            $0.edges.equalTo(self.view.usnp.edges)
        }
        
        loadDataSource()
        
        if let printer = PrinterManager.instance.accessory?.escPrinter {
            printer.escPrinterStatusListener = {
                if $0.isEmpty {
                    SVProgressHUD.showSuccess(withStatus: $0.description)
                }else {
                    SVProgressHUD.showError(withStatus: $0.description)
                }
            }
        }
    }
    
    deinit {
        if let printer = PrinterManager.instance.accessory?.escPrinter {
            printer.escPrinterStatusListener = nil
        }
    }
    
    private func loadDataSource() {
        
        functions.removeAll()
        var item : PDSettingItem
        
        item = PDSettingItem.init(title: "Custom text Sample".localized, detailTitle: nil, target: self, selector: #selector(pushAutoTextVC))
        functions.append(item)
        
        item = PDSettingItem.init(title: "Self-test page Sample".localized, detailTitle: nil, target: nil, selector: #selector(PDESCTestFunctions.printSelfTestPage))
        functions.append(item)
        
        item = PDSettingItem.init(title: "Device Status Sample".localized, detailTitle: nil, target: nil, selector: #selector(PDESCTestFunctions.getPrinterStatus))
        functions.append(item)
        
        item = PDSettingItem.init(title: "Barcode Sample".localized, detailTitle: nil, target: nil, selector: #selector(PDESCTestFunctions.printBarcode))
        functions.append(item)
        
        item = PDSettingItem.init(title: "Page Mode Sample".localized, detailTitle: nil, target: nil, selector: #selector(PDESCTestFunctions.testPageModeSample))
        functions.append(item)
        
        item = PDSettingItem.init(title: "Bill Sample".localized, detailTitle: nil, target: nil, selector: #selector(PDESCTestFunctions.testBillSample))
        functions.append(item)
        
        item = PDSettingItem.init(title: "Bitmap Sample".localized, detailTitle: nil, target: self, selector: #selector(self.pushSystenPhoto))
        functions.append(item)
        
        item = PDSettingItem.init(title: "Command File Print".localized, detailTitle: nil, target: self, selector: #selector(self.selectDocument))
        functions.append(item)
        
        item = PDSettingItem.init(title: "Printer firmware upgrade".localized, detailTitle: nil, target: self, selector: #selector(self.updateDeviceFirmware))
        functions.append(item)
        
        item = PDSettingItem.init(title: "POS Bill Sample".localized, detailTitle: nil, target: nil, selector: #selector(PDESCTestFunctions.testPOSPrinterSample))
        functions.append(item)
        
        item = PDSettingItem.init(title: "POS Image Sample".localized, detailTitle: nil, target: nil, selector: #selector(PDESCTestFunctions.testPOSImageSample))
        functions.append(item)
        
        item = PDSettingItem.init(title: "Set the siyuan bold(Chinese)".localized, detailTitle: nil, target: nil, selector: #selector(PDESCTestFunctions.setSesFontForChinese))
        functions.append(item)
        
        item = PDSettingItem.init(title: "Set the siyuan bold(English)".localized, detailTitle: nil, target: nil, selector: #selector(PDESCTestFunctions.setSesFontForEnglish))
        functions.append(item)
        
        item = PDSettingItem.init(title: "Drawer Test".localized, detailTitle: nil, target: nil, selector: #selector(PDESCTestFunctions.testDrawer))
        functions.append(item)
        
        item = PDSettingItem.init(title: "设置字体大小".localized, detailTitle: nil, target: self, selector: #selector(showFontSizeDialog))
        functions.append(item)
        
        if PrinterManager.instance.printers.count > 1 {
            item = PDSettingItem.init(title: "Self-test page Sample for multiple devices".localized, detailTitle: nil, target: nil, selector: #selector(PDESCTestFunctions.batchSendPrintSelfTest))
            functions.append(item)
        }
        
        if let printer = PrinterManager.instance.accessory {
            
            item = PDSettingItem.init(title: "Prevent missed calls".localized, block: { [weak self] _ in
                
                guard let imgaePath = Bundle.main.path(forResource: "black02", ofType: "png") else {return}
                guard let cgTemp = UIImage.init(contentsOfFile: imgaePath)?.cgImage else {return}
                
                let cmd = PTCommandESC.init()
                cmd.appendRasterImage(cgTemp, mode: .binary, compress: .LZO, package: false)
                cmd.setFullCutWithDistance(100)
                
                SVProgressHUD.showProgress(0, status: "Sending data".localized)
                
                printer.escPrinter.preventMissedPrint(withJobId: cmd, timeout: 30, retry: { error in
                    SVProgressHUD.showProgress(1, status: "Print fail".localized + "\n" + "等待重打中...".localized)
                }, complete: { error in
                    SVProgressHUD.dismiss()
                    if let error = error {
                        self?.show(S1ErrorDescription(error: error))
                        return
                    }
                    self?.show("Print Success".localized)
                }, sendProgress: { progress in
                    SVProgressHUD.showProgress(Float(progress.fractionCompleted), status: "Sending data".localized)
                })
            })
            functions.append(item)
        }

        item = PDSettingItem.init(title: "Beeper Pattern Sample".localized, block: { [weak self] _ in
            guard let self = self else { return }
            let patterns: [ESCBeeperPattern] = ESCBeeperPattern.allCases
            self.valuePick(patterns) { p in
                let esc = PTCommandESC()
                esc.escBeepIntegratedBeeper(with: p, times: 3, t1: 10, t2: 10)
                PrinterManager.instance.executeCmd(esc)
            }
        })
        functions.append(item)
    }
    
}

extension PDESCViewController : UITableViewDelegate,UITableViewDataSource {
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return functions.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        var cell = tableView.dequeueReusableCell(withIdentifier: "iden")
        if cell == nil {
            cell = UITableViewCell.init(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "iden")
        }
        cell?.textLabel?.text = functions[indexPath.row].title
        cell?.textLabel?.textColor = UIColor.black
        
        return cell!
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        let action = functions[indexPath.row]
        if let block = action.block {
            block(action.title)
            return
        }
        if let target = action.target {
            if let selector = action.selector {
                target.perform(selector)
            }
        }else {
            if let selector = action.selector {
                PDESCTestFunctions.perform(selector)
            }
        }
    }
}

extension PDESCViewController {
    
    @objc func pushAutoTextVC() {
        
        self.navigationController?.pushViewController(PDPrintTextViewController(with: PTCommandType.ESC), animated: true)
    }
    
    //MARK:print image
    @objc func pushSystenPhoto() {
        
        let photoPickerVC = PDPhotoListViewController.init(with: PTCommandType.ESC)
        navigationController?.pushViewController(photoPickerVC, animated: true)
    }
    
    @objc func selectDocument() {
        
        self.selectDocumentType = PDDocumentPickerView.commandDocument
        let picker = UIDocumentPickerViewController.init(documentTypes: ["public.data"], in: .import)
        picker.delegate = self
        picker.modalPresentationStyle = .fullScreen
        if #available(iOS 11.0, *) {
            picker.allowsMultipleSelection = false
        } else {
            // Fallback on earlier versions
        }
        self.present(picker, animated: true, completion: nil)
    }
    
    @objc func updateDeviceFirmware() {
        
        UIAlertController.showActionAlert("Tips".localized, message: "This function is only for some models, please confirm whether your printer supports the function, if it supports, please select the printer firmware to upgrade".localized, confirm: "OK".localized) { (_) in
            self.selectDocumentType = PDDocumentPickerView.firmwareBin
            let picker = UIDocumentPickerViewController.init(documentTypes: ["public.data"], in: .import)
            picker.delegate = self
            picker.modalPresentationStyle = .fullScreen
            if #available(iOS 11.0, *) {
                picker.allowsMultipleSelection = false
            } else {
                // Fallback on earlier versions
            }
            self.present(picker, animated: true, completion: nil)
        }
    }
    
    @objc func showFontSizeDialog() {
        let alert = UIAlertController(title: "设置字体大小".localized, message: "", preferredStyle: .actionSheet)
        
        let smallAction = UIAlertAction(title: "小号".localized, style: .default) { _ in
            PDESCTestFunctions.applyFontSize(0, sizeText: "小号")
        }
        
        let mediumAction = UIAlertAction(title: "中号".localized, style: .default) { _ in
            PDESCTestFunctions.applyFontSize(1, sizeText: "中号")
        }
        
        let largeAction = UIAlertAction(title: "大号".localized, style: .default) { _ in
            PDESCTestFunctions.applyFontSize(2, sizeText: "大号")
        }
        
        let extraLargeAction = UIAlertAction(title: "特大号".localized, style: .default) { _ in
            PDESCTestFunctions.applyFontSize(3, sizeText: "特大号")
        }
        
        let cancelAction = UIAlertAction(title: "取消".localized, style: .cancel)
        
        alert.addAction(smallAction)
        alert.addAction(mediumAction)
        alert.addAction(largeAction)
        alert.addAction(extraLargeAction)
        alert.addAction(cancelAction)
        
        present(alert, animated: true)
    }
}

extension PDESCViewController: UIDocumentPickerDelegate {
    
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
        
        sendData(from: url)
    }
    
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        
        sendData(from: urls[0])
    }
    
    func sendData(from url: URL) -> Void {
        
        switch self.selectDocumentType {
            case .commandDocument:
                let alertControl = UIAlertController(title: "Tips".localized, message: "Please select the mode of sending data".localized, preferredStyle: UIAlertController.Style.alert)
                alertControl.addTextField { (textTF) in
                    textTF.placeholder = "Please enter the number of copies".localized
                }
                
                let cancel = UIAlertAction(title: "Cancel".localized, style: UIAlertAction.Style.cancel, handler: nil)
                let strConfirm = UIAlertAction(title: "Text mode".localized, style: UIAlertAction.Style.default) { [weak alertControl](_) in
                    guard let alert = alertControl else { return }
                    guard let position = alert.textFields?.first, var temp = position.text else { return }
                    if temp.isEmpty {
                        temp = "1"
                    }
                    
                    if let resultInt = Int(temp) {
                        
                        guard let data = try? Data.init(contentsOf: url) else {
                            SVProgressHUD.showError(withStatus: "Get File failed".localized)
                            return
                        }
                        
                        guard let utf_string = PTEncode.decodeString(with: data) else {
                            SVProgressHUD.showInfo(withStatus: "The file is not supported".localized)
                            return
                        }
                        
                        guard let fileData = PTEncode.encodeData(with: utf_string) else {
                            SVProgressHUD.showInfo(withStatus: "The file is not supported".localized)
                            return
                        }
                        
                        var sendData = Data()
                        
                        for _ in 0..<resultInt {
                            sendData.append(fileData)
                        }
                        SVProgressHUD.showProgress(0)
                        PrinterManager.instance.accessory?.write(sendData, progress: { progress in
                            if progress.isFinished {
                                SVProgressHUD.showSuccess(withStatus: "Data sent successfully".localized)
                                return
                            }
                            SVProgressHUD.showProgress(Float(progress.completedUnitCount))
                        })
                    }else {
                        SVProgressHUD.showError(withStatus: "Incorrect input, please re-enter".localized)
                    }
                }
                
                let hexConfirm = UIAlertAction(title: "Hex mode".localized, style: UIAlertAction.Style.default) { [weak alertControl](_) in
                    guard let alert = alertControl else { return }
                    guard let position = alert.textFields?.first, var temp = position.text else { return }
                    if temp.isEmpty {
                        temp = "1"
                    }
                    
                    if let resultInt = Int(temp) {
                        
                        guard let data = try? Data.init(contentsOf: url) else {
                            SVProgressHUD.showError(withStatus: "Get File failed".localized)
                            return
                        }
                        
                        guard let utf_string = String.init(data: data, encoding: String.Encoding.ascii) else {
                            SVProgressHUD.showInfo(withStatus: "The file is not supported".localized)
                            return
                        }
                        
                        guard let fileData = try? utf_string.hexStringToData() else {
                            SVProgressHUD.showInfo(withStatus: "Irregular HEX data".localized)
                            return
                        }
                        
                        var sendData = Data()
                        
                        for _ in 0..<resultInt {
                            sendData.append(fileData)
                        }
                        
                        SVProgressHUD.showProgress(0)
                        PrinterManager.instance.accessory?.write(sendData, progress: { progress in
                            if progress.isFinished {
                                SVProgressHUD.showSuccess(withStatus: "Data sent successfully".localized)
                                return
                            }
                            SVProgressHUD.showProgress(Float(progress.completedUnitCount))
                        })
                        
                    }else {
                        SVProgressHUD.showError(withStatus: "Incorrect input, please re-enter".localized)
                    }
                }
                
                alertControl.addAction(strConfirm)
                alertControl.addAction(hexConfirm)
                alertControl.addAction(cancel)
                self.present(alertControl, animated: true, completion: nil)
            
            case .firmwareBin:
                UIAlertController.showActionAlert("Tips".localized, message: "Are you sure to upgrade the printer firmware?".localized, confirm: "OK".localized) { (_) in
                    
                    guard let deviceData = try? Data.init(contentsOf: url) else {
                        SVProgressHUD.showError(withStatus: "Get File failed".localized)
                        return
                    }
                    
                    let result = PTCommandCommon.getUpdatePrinterFirmwarePackage()
                    PrinterManager.instance.dataRequest(result) { result in
                        switch result {
                        case .success(let data):
                            guard let temp = data.readValue(as: UInt32.self) else { return }
                            let package = Int(temp)
                            self.updateDevice(deviceData, package: package)
                        case .failure(let error):
                            SVProgressHUD.showError(withStatus: S1ErrorDescription(error: error))
                        }
                    }
            }
        }
    }
    
    private func updateDevice(_ data:Data, package:Int) {
        
        PrinterManager.instance.firmwareUpgrade(data, packageSize: package) { progress in
            SVProgressHUD.showProgress(Float(progress.fractionCompleted))
        } complete: { error in
            if let error = error {
                SVProgressHUD.showError(withStatus: S1ErrorDescription(error: error))
                return
            }
            SVProgressHUD.showSuccess(withStatus: "升级成功")
        }
    }
}
