//
//  PDMainViewController.swift
//  PrinterDemo
//
//  Created by ios on 2019/9/6.
//  Copyright © 2019 XiamenHY. All rights reserved.
//

import UIKit
import PrinterSDK
import SVProgressHUD
import RYCommunication

enum PDSectionIndex : Int {
    case device = 0
    case command
    case function
    case appendix
}

class PDMainViewController: PDBaseViewController {

    private lazy var tableView : UITableView = {
        let tw = UITableView(frame: CGRect.zero, style: UITableView.Style.grouped)
        tw.delegate = self
        tw.dataSource = self
        tw.rowHeight = 50
        tw.backgroundColor = UIColor.white
        tw.showsVerticalScrollIndicator = false
        tw.separatorStyle = UITableViewCell.SeparatorStyle.singleLine
        if #available(iOS 15.0, *) {
            tw.sectionHeaderTopPadding = 0
        }
        return tw
    }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        navigationItem.title = "\(AppInfo.version) build \(AppInfo.build)"
        navigationItem.leftBarButtonItem = UIBarButtonItem.init(title: "Connect".localized, style: UIBarButtonItem.Style.plain, target: self, action: #selector(showConnectType))
        kUserDefaults.set(true, forKey: PDPaperType)
        navigationItem.rightBarButtonItem = UIBarButtonItem.init(
            title: "跨网段配网".localized,
            style: UIBarButtonItem.Style.plain,
            target: self,
            action: #selector(udpNetConfig)
        )
    }
    
    @objc func udpNetConfig() {
        let temp = UDPNetConfigScanViewController()
        self.show(temp, sender: nil)
    }
    func filterCharacters(_ version:String) -> String {

        var result = ""
        for cha in version {
            let predicateStr: String = "^[0-9.]{1}$"
            let predicate = NSPredicate(format: "SELF MATCHES %@", predicateStr)
            if predicate.evaluate(with: String(cha)) {
                result.append(cha)
            }
        }
        return result
    }
    
    override func configUI() {
        
        view.addSubview(tableView)
        tableView.snp.makeConstraints {
            $0.edges.equalTo(self.view.usnp.edges)
        }
        PrinterManager.instance.addConnectListen(self) { [weak self] printer, status  in
            switch (status) {
            case .connected:
                self?.tableView.reloadData()
            default:
                SVProgressHUD.showInfo(withStatus: "Disconnected".localized)
                PrinterManager.instance.removePrinter(printer)
                self?.tableView.reloadData()
                if PrinterManager.instance.printers.count == 0{
                    self?.navigationController?.popToRootViewController(animated: true)
                }
            }
        }
    }
}

extension PDMainViewController : UITableViewDelegate,UITableViewDataSource {
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return PDSectionIndex.appendix.rawValue + 1
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        var title = ""
        
        switch PDSectionIndex.init(rawValue: section)?.rawValue {
        case PDSectionIndex.device.rawValue:
            title = "Destination Device".localized
        case PDSectionIndex.command.rawValue:
            title = "Printer Command".localized
        case PDSectionIndex.function.rawValue:
            title = "功能".localized
        case PDSectionIndex.appendix.rawValue:
            title = "Appendix".localized
        case .none:
            title = ""
        case .some(_):
            title = ""
        }
         return title
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == PDSectionIndex.device.rawValue {
            if PrinterManager.instance.printers.count > 0{
                return PrinterManager.instance.printers.count
            }
            return 1
        }
        if section == PDSectionIndex.command.rawValue {
            return 4
        }
        if section == PDSectionIndex.function.rawValue {
            return 8
        }
        if section == PDSectionIndex.appendix.rawValue {
            return 2
        }
        return 1
    }
    
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 40
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 0.01
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCell(withIdentifier: "iden")
        cell?.accessoryType = UITableViewCell.AccessoryType.none
        if indexPath.section == 0 {
            if cell == nil {
                cell = UITableViewCell.init(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "iden")
            }
            if cell != nil {
                if !PrinterManager.instance.connected {
                    cell?.backgroundColor = UIColor(red: 0.8, green: 0.9, blue: 1.0, alpha: 1.0)
                    
                    cell?      .textLabel!.text = "Unconnected".localized
                    cell?.detailTextLabel!.text = ""
                    
                    cell?      .textLabel!.textColor = UIColor.theme
                    cell?.detailTextLabel!.textColor = UIColor.theme
                    
                    UIView.beginAnimations(nil, context: nil)
                    
                    cell?      .textLabel!.alpha = 0.0
                    cell?.detailTextLabel!.alpha = 0.0
                    
                    UIView.setAnimationDelay             (0.0)                             // 0mS!!!
                    UIView.setAnimationDuration          (0.6)                             // 600mS!!!
                    UIView.setAnimationRepeatCount       (Float(UINT32_MAX))
                    UIView.setAnimationRepeatAutoreverses(true)
                    UIView.setAnimationCurve             (UIView.AnimationCurve.easeIn)
                    
                    cell?      .textLabel!.alpha = 1.0
                    cell?.detailTextLabel!.alpha = 1.0
                    
                    UIView.commitAnimations()
                }else {
                    let device = PrinterManager.instance.printers[indexPath.row]
                    cell?.textLabel?.text = device.name
                    cell?.textLabel?.textColor = UIColor.black
                }
                cell?.accessoryType = UITableViewCell.AccessoryType.disclosureIndicator
                cell?.isUserInteractionEnabled = true
            }
        }else {
            cell?.backgroundColor = UIColor.white
            if indexPath.section == 1 {
                let cmdTypes = ["CPCL","ESC","TSPL","ZPL"]
                if cell == nil {
                    cell = UITableViewCell.init(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "iden")
                }
                cell?      .textLabel!.text = cmdTypes[indexPath.row]
                cell?.detailTextLabel!.text = ""
                
                cell?      .textLabel!.textColor = UIColor.titleColor
                cell?.detailTextLabel!.textColor = UIColor.titleColor
                cell?.accessoryType = UITableViewCell.AccessoryType.disclosureIndicator
            }
            else if indexPath.section == 2 {
                let functions = [
                    "蓝牙配网".localized,
                    "读取状态".localized,
                    "读取打印机Wi-Fi热点".localized,
                    "读取已保存 Wi-Fi 列表".localized,
                    "读取当前连接 Wi-Fi".localized,
                    "添加并连接 Wi-Fi".localized,
                    "连接已保存 Wi-Fi".localized,
                    "删除已保存 Wi-Fi".localized
                ]
                if cell == nil {
                    cell = UITableViewCell.init(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "iden")
                }
                
                cell?      .textLabel!.text = functions[indexPath.row]
                cell?.detailTextLabel!.text = ""
                
                cell?      .textLabel!.textColor = UIColor.black
                cell?.detailTextLabel!.textColor = UIColor.black
                cell?.accessoryType = UITableViewCell.AccessoryType.disclosureIndicator
            }
            else if indexPath.section == 3 {
                let appdixs = ["查看日志".localized,"删除日志".localized,"PrinterSDK version".localized]
                if cell == nil {
                    cell = UITableViewCell.init(style: UITableViewCell.CellStyle.subtitle, reuseIdentifier: "iden")
                }
                
                cell?      .textLabel!.text = appdixs[indexPath.row]
                cell?.detailTextLabel!.text = ""
                
                cell?      .textLabel!.textColor = UIColor.black
                cell?.detailTextLabel!.textColor = UIColor.black
            }
            
        }
        
        return cell!
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        let selectedSection = PDSectionIndex.init(rawValue: indexPath.section)!
        switch (selectedSection,indexPath.row) {
        case (PDSectionIndex.device,0):
            guard PrinterManager.instance.printers.count > 0 else{
                showConnectType()
                return
            }
            let printer = PrinterManager.instance.printers[indexPath.row]
            UIAlertController.showActionAlert("确认断开连接?".localized, message: "", confirm: "确定".localized) { _ in
                printer.disconnect()
            }
        case (PDSectionIndex.command, let row):
            if row == 0 {
                let alert = UIAlertController(title: "Please select the type of paper you want to print".localized, message: nil, preferredStyle: .alert)
                let continueAction = UIAlertAction.init(title: "Continuous paper".localized, style: UIAlertAction.Style.default) { (_) in
                    kUserDefaults.set(false, forKey: PDPaperType)
                    self.navigationController?.pushViewController(PDCPCLViewController(), animated: true)
                }
                
                let labelAction = UIAlertAction.init(title: "Label".localized, style: UIAlertAction.Style.default) { (_) in
                    kUserDefaults.set(true, forKey: PDPaperType)
                    self.navigationController?.pushViewController(PDCPCLViewController(), animated: true)
                }
                alert.addAction(continueAction)
                alert.addAction(labelAction)
                self.present(alert, animated: true, completion: nil)
            }else if row == 1 {
                self.navigationController?.pushViewController(PDESCViewController(), animated: true)
            }else if row == 2 {
                self.navigationController?.pushViewController(PDTSPLViewController(), animated: true)
            }else if row == 3 {
                self.navigationController?.pushViewController(PDZPLViewController(), animated: true)
            }
        case (PDSectionIndex.function, let row):
            if row == 0 {
                self.navigationController?.pushViewController(NetworkConfigViewController(), animated: true)
            }else if row == 1 {
                self.navigationController?.pushViewController(PDInfoViewController(), animated: true)
            }else if row == 2 {
                // WiFi热点扫描功能
                self.navigationController?.pushViewController(PDWifiHotspotsViewController(), animated: true)
            }else if row == 3 {
                self.showSavedWifiList()
            }else if row == 4 {
                self.showCurrentConnectedWifi()
            }else if row == 5 {
                self.promptAddAndConnectWifi()
            }else if row == 6 {
                self.promptConnectSavedWifi()
            }else if row == 7 {
                self.promptDeleteSavedWifi()
            }
        case (PDSectionIndex.appendix, let row):
            
            if row == 0 {
                self.navigationController?.pushViewController(PDLogViewController(), animated: true)
            }else {
                if PTLog.shareInstance().removeFile() {
                    SVProgressHUD.showSuccess(withStatus: "successfully deleted".localized)
                }else {
                    SVProgressHUD.showInfo(withStatus: "No log".localized)
                }
            }
        default:
            break
        }
        
    }
}

//connect
extension PDMainViewController {
    
    @objc private func showConnectType() {
        
        guard let rootVC = PDAppWindow.rootViewController  else { return }
        let alert = UIAlertController.init(title: "Please select a connect type".localized, message:nil, preferredStyle: .alert)
        
        let action1 = UIAlertAction.init(title: "Bluetooth Low Energy".localized, style: .default) { _ in
            self.pushBleController()
        }
        let action2 = UIAlertAction.init(title: "Wi-Fi(Auto)".localized, style: .default) { _ in
            self.pushWifiAutoController()
        }
        let action3 = UIAlertAction.init(title: "Wi-Fi(Manual)".localized, style: .default) { _ in
            self.inputIpToConnect()
        }
        let action5 = UIAlertAction.init(title: "Cancel".localized, style: .cancel, handler: nil)
        
        alert.addAction(action1)
        alert.addAction(action2)
        alert.addAction(action3)
        alert.addAction(action5)
        rootVC.present(alert, animated: true, completion: nil)
    }
    
    @objc private func pushBleController() {
        navigationController?.pushViewController(PDBLEViewController(), animated: true)
    }
    
    @objc private func inputIpToConnect() {
        self.presentInputAlertController(
            msg: "输入ip".localized,
            defaultText: UserDefaults.standard.getDefaultIp(),
            inputDesc: "", closure: {
            /// 构造PTPrinter对象进行连接
            SVProgressHUD.show(withStatus: "Connecting, pls. wait".localized)
            let printer = RYSocketAccessory($0, port: 9100)
            self.tryAddPrinter(printer)
        })
    }
    
    @objc private func pushWifiAutoController() {
        navigationController?.pushViewController(PDWiFiViewController(), animated: true)
    }

    private func currentPrinter() -> S1V1ProtocolPrinter? {
        guard let printer = PrinterManager.instance.accessory, printer.connected else {
            SVProgressHUD.showInfo(withStatus: "请先连接打印机".localized)
            return nil
        }
        return printer
    }

    private func showSavedWifiList() {
        guard let printer = currentPrinter() else { return }
        SVProgressHUD.show(withStatus: "正在获取已保存 Wi-Fi 列表...".localized)
        printer.getSavedWifiList { [weak self] wifiList, error in
            DispatchQueue.main.async {
                SVProgressHUD.dismiss()
                if let error = error {
                    self?.show(error.localizedDescription)
                    return
                }
                let text = wifiList?.isEmpty == false ? wifiList!.joined(separator: "\n") : "暂无已保存 Wi-Fi".localized
                self?.show(text)
            }
        }
    }

    private func showCurrentConnectedWifi() {
        guard let printer = currentPrinter() else { return }
        SVProgressHUD.show(withStatus: "正在获取当前连接 Wi-Fi...".localized)
        printer.getCurrentConnectedWifi { [weak self] ssid, error in
            DispatchQueue.main.async {
                SVProgressHUD.dismiss()
                if let error = error {
                    self?.show(error.localizedDescription)
                    return
                }
                self?.show(ssid ?? "未连接 Wi-Fi".localized)
            }
        }
    }

    private func promptAddAndConnectWifi() {
        presentWiFiCredentialAlert(title: "添加并连接 Wi-Fi".localized, ssid: nil) { [weak self] ssid, password in
            guard let self = self, let printer = self.currentPrinter() else { return }
            SVProgressHUD.show(withStatus: "正在配置并连接 Wi-Fi，等待打印机上线...".localized)
            printer.addAndConnectWifi(ssid, password: password) { error in
                DispatchQueue.main.async {
                    SVProgressHUD.dismiss()
                    if let error = error {
                        self.show(error.localizedDescription)
                        return
                    }
                    self.show("Wi-Fi 已配置并上线".localized)
                }
            }
        }
    }

    private func promptConnectSavedWifi() {
        guard let printer = currentPrinter() else { return }
        SVProgressHUD.show(withStatus: "正在获取已保存 Wi-Fi 列表...".localized)
        printer.getSavedWifiList { [weak self] wifiList, error in
            DispatchQueue.main.async {
                SVProgressHUD.dismiss()
                guard let self = self else { return }
                if let error = error {
                    self.show(error.localizedDescription)
                    return
                }
                let list = wifiList ?? []
                guard !list.isEmpty else {
                    self.show("暂无已保存 Wi-Fi".localized)
                    return
                }
                self.presentWifiSelection(title: "选择要连接的 Wi-Fi".localized, items: list) { [weak self] ssid in
                    guard let self = self, let printer = self.currentPrinter() else { return }
                    SVProgressHUD.show(withStatus: "正在切换 Wi-Fi，等待打印机上线...".localized)
                    printer.connectSavedWifi(ssid) { error in
                        DispatchQueue.main.async {
                            SVProgressHUD.dismiss()
                            if let error = error {
                                self.show(error.localizedDescription)
                                return
                            }
                            self.show("Wi-Fi 已切换并上线".localized)
                        }
                    }
                }
            }
        }
    }

    private func promptDeleteSavedWifi() {
        guard let printer = currentPrinter() else { return }
        SVProgressHUD.show(withStatus: "正在获取已保存 Wi-Fi 列表...".localized)
        printer.getSavedWifiList { [weak self] wifiList, error in
            DispatchQueue.main.async {
                SVProgressHUD.dismiss()
                guard let self = self else { return }
                if let error = error {
                    self.show(error.localizedDescription)
                    return
                }
                let list = wifiList ?? []
                guard !list.isEmpty else {
                    self.show("暂无已保存 Wi-Fi".localized)
                    return
                }
                self.presentWifiSelection(title: "选择要删除的 Wi-Fi".localized, items: list) { [weak self] ssid in
                    guard let self = self, let printer = self.currentPrinter() else { return }
                    SVProgressHUD.show(withStatus: "正在删除 Wi-Fi...".localized)
                    printer.deleteSavedWifi(ssid) { error in
                        DispatchQueue.main.async {
                            SVProgressHUD.dismiss()
                            if let error = error {
                                self.show(error.localizedDescription)
                                return
                            }
                            self.show("删除成功".localized)
                        }
                    }
                }
            }
        }
    }

    private func presentSimpleWifiInput(title: String, placeholder: String, completion: @escaping (String) -> Void) {
        let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert)
        alert.addTextField { textField in
            textField.placeholder = placeholder
            textField.keyboardType = .default
        }
        alert.addAction(UIAlertAction(title: "Cancel".localized, style: .cancel))
        alert.addAction(UIAlertAction(title: "OK".localized, style: .default) { [weak alert] _ in
            guard let text = alert?.textFields?.first?.text?.trimmingCharacters(in: .whitespacesAndNewlines), !text.isEmpty else { return }
            completion(text)
        })
        present(alert, animated: true)
    }

    private func presentWiFiCredentialAlert(title: String, ssid: String?, completion: @escaping (String, String) -> Void) {
        let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert)
        alert.addTextField { textField in
            textField.placeholder = "SSID"
            textField.keyboardType = .default
            textField.text = ssid
        }
        alert.addTextField { textField in
            textField.placeholder = "Password"
            textField.isSecureTextEntry = true
        }
        alert.addAction(UIAlertAction(title: "Cancel".localized, style: .cancel))
        alert.addAction(UIAlertAction(title: "OK".localized, style: .default) { [weak alert] _ in
            guard let fields = alert?.textFields, fields.count >= 2 else { return }
            let ssidText = fields[0].text?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
            let passwordText = fields[1].text ?? ""
            guard !ssidText.isEmpty else { return }
            completion(ssidText, passwordText)
        })
        present(alert, animated: true)
    }

    private func presentWifiSelection(title: String, items: [String], completion: @escaping (String) -> Void) {
        let alert = UIAlertController(title: title, message: nil, preferredStyle: .actionSheet)
        for item in items {
            alert.addAction(UIAlertAction(title: item, style: .default) { _ in
                completion(item)
            })
        }
        alert.addAction(UIAlertAction(title: "Cancel".localized, style: .cancel))
        if let popover = alert.popoverPresentationController {
            popover.sourceView = view
            popover.sourceRect = CGRect(x: view.bounds.midX, y: view.bounds.midY, width: 1, height: 1)
        }
        present(alert, animated: true)
    }
}
