//
//  HPRTBleConnectViewController.swift
//  Example
//
//  Created by ldc on 2020/11/12.
//

import UIKit
import SVProgressHUD
import RYCommunication

struct HPRTBleConnectParams<T: RYAccessory> {
    
    let convertor: (RYBleAccessory) -> T
    
    let didConnect: (T) -> Void
    
    init(convertor: @escaping (RYBleAccessory) -> T, didConnect: @escaping (T) -> Void) {
        self.convertor = convertor
        self.didConnect = didConnect
    }
}

class HPRTBleConnectViewController<T: RYAccessory>: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    let params: HPRTBleConnectParams<T>
    
    init(params: HPRTBleConnectParams<T>) {
        self.params = params
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    lazy var tableView: UITableView = {
        let temp = UITableView.init(frame: view.bounds, style: .grouped)
        if #available(iOS 15.0, *) {
            temp.sectionHeaderTopPadding = 0
        } else {
            // Fallback on earlier versions
        }
        temp.autoresizingMask = [
            .flexibleWidth,
            .flexibleHeight
        ]
        temp.delegate = self
        temp.rowHeight = 60
        temp.dataSource = self
        return temp
    }()
    
    let manager = RYCentralManager.share()
    var printer: Any?
    var printers = [RYBleAccessory]()
    
    var iden: String?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = UIColor.white
        title = "蓝牙搜索"
        view.addSubview(tableView)
        startScan()
    }
    
    func startScan() -> Void {
        
        self.iden = manager.startScan(-1) { [weak self] (accessory) in
            if let index = self?.printers.firstIndex(where: { temp in
                return temp.name == accessory.name
            }) {
                self?.printers[index] = accessory
            }else {
                self?.printers.append(accessory)
                self?.tableView.reloadData()
            }
        } powerOffBlock: { [weak self] in
            print("power off")
            self?.iden = nil
            self?.printers = []
            self?.tableView.reloadData()
        } scanTimeoutBlock: { [weak self] in
            print("timeout")
            self?.iden = nil
        } printerFilter: { peripheral, _, _ in
            guard let name = peripheral.name else { return false }
            return !name.isEmpty
        }

    }
    
    deinit {
        if let iden = self.iden {
            manager.stopScan(iden)
        }
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        
        return 0.01
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        
        return nil
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        
        return 0.01
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        
        return nil
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        return printers.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "iden") ?? UITableViewCell.init(style: .default, reuseIdentifier: "iden")
        let printers = printers
        cell.textLabel?.text = printers[indexPath.row].peripheral.name
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        tableView.deselectRow(at: indexPath, animated: true)
        let bleAccessory = printers[indexPath.row]
        bleAccessory.services = [FF00BleService()]
        let printer = params.convertor(bleAccessory)
        self.printer = printer
        SVProgressHUD.show(withStatus: "连接中...")
        printer.connect({
            SVProgressHUD.dismiss()
            self.params.didConnect(printer)
        }) { (error) in
            self.printer = nil
            SVProgressHUD.dismiss()
            
            var msg: String
            switch ((error as NSError).domain, (error as NSError).code) {
            case (RYBleConnectErrorDomain, RYBleConnectErrorCode.timeout.rawValue):
                msg = "连接接超时"
            case (RYBleConnectErrorDomain, RYBleConnectErrorCode.systemError.rawValue):
                msg = "系统错误"
            case (RYBleConnectErrorDomain, RYBleConnectErrorCode.serviceNotFound.rawValue):
                msg = "没有找到对应的BLE服务"
            case (RYBleConnectErrorDomain, RYBleConnectErrorCode.characteristicNotFound.rawValue):
                msg = "没有找到对应的BLE特征"
            case (RYBleConnectErrorDomain, RYBleConnectErrorCode.authFail.rawValue):
                msg = "授权失败"
            case (RYBleConnectErrorDomain, RYBleConnectErrorCode.authTimeout.rawValue):
                msg = "授权超时"
            default:
                msg = String.init(format: "%@-%i", (error as NSError).domain, (error as NSError).code)
            }
            self.bk_presentWarningAlertController(title: "提示", message: "连接失败: \(msg)", style: .destructive)
        }
    }
}
