import Cocoa

class DevListTableViewController: NSViewController {
    
    private var btDevices:Array<MPosDeviceInfo> = []
    private var bleDevices:Array<MPosDeviceInfo> = []
    private var networkDevices:Array<MPosDeviceInfo> = []
    private var usbDevices:Array<MPosDeviceInfo> = []
    
    private var devices:Array<MPosDeviceInfo> = []
    
    @IBOutlet weak var spinner: NSProgressIndicator!
    @IBOutlet weak var tableView: NSTableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        btDevices = []
        networkDevices = []
        bleDevices = []
        usbDevices = []
        devices = []
        tableView.target = self
        tableView.doubleAction = #selector(tableViewDoubleAction);
    }
    
    @objc func tableViewDoubleAction(_ sender:Any) {
        self.dismiss(self)
    }
    
    override func viewDidAppear() {
        DispatchQueue.global(qos: .default).async { [weak self] in
            guard let strongSelf = self else { return }
            strongSelf.setIsHiddenSpinner(isHidden: false)
            let lookup = MPosLookup()
            strongSelf.btDevices = lookup.getBluetoothDevices()
//            strongSelf.networkDevices = lookup.getNetworkDevices()
            strongSelf.networkDevices = UDPSetting.getNetworkInfos()
            strongSelf.bleDevices = lookup.getBLEDevices()
            strongSelf.usbDevices = lookup.getUSBDevices()
            
            strongSelf.devices.append(contentsOf: strongSelf.btDevices)
            strongSelf.devices.append(contentsOf: strongSelf.networkDevices)
            strongSelf.devices.append(contentsOf: strongSelf.bleDevices)
            strongSelf.devices.append(contentsOf: strongSelf.usbDevices)
            
            DispatchQueue.main.async {
                strongSelf.tableView.reloadData()
                strongSelf.setIsHiddenSpinner(isHidden: true)
            }
        }
    }
    
    func setIsHiddenSpinner(isHidden:Bool) {
        DispatchQueue.main.async { [weak self] in
            guard let strongSelf = self else { return }
            strongSelf.spinner.isHidden = isHidden
            if isHidden {
                strongSelf.spinner.stopAnimation(nil)
            } else {
                strongSelf.spinner.startAnimation(nil)
            }
        }
    }
    
    @IBAction func onClose(_ sender: Any) {
        tableViewDoubleAction(sender)
    }
}

extension DevListTableViewController: NSTableViewDataSource {
    func numberOfRows(in tableView: NSTableView) -> Int {
        return devices.count
    }
}

extension DevListTableViewController: NSTableViewDelegate {
    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        if row > devices.count {
            return nil
        }
        
        var identifier = ""
        var text = ""
        
        let device = devices[row]
        
        if tableColumn == tableView.tableColumns[0] {
            identifier = "Interface"
            switch device.interfaceType {
            case .WIFI: fallthrough
            case .ETHERNET: text = "Network"
            case .BLUETOOTH: text = "Bluetooth"
            case .BLE: text = "BLE"
            case .USB: text = "USB"
            @unknown default: text = "Unknown"
            }
        } else if tableColumn == tableView.tableColumns[1] {
            identifier = "Info"
            switch device.interfaceType {
            case .WIFI: fallthrough
            case .ETHERNET: text = String(format: "%@ (%@:%@)", device.name.count > 0 ? device.name : "Network Device", device.address, device.portNumber)
            case .BLUETOOTH: text = String(format: "%@ (%@)", device.name, device.macAddress)
            case .BLE: text = String(format: "%@ (%@)", device.name.count > 0 ? device.name : "BLE Device", device.macAddress)
            case .USB: text = String(format: "%@ (%@)", device.name.count > 0 ? device.name : "USB Device", device.address)
            @unknown default: text = "Unknown"
            }
        }
        
        guard let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(identifier), owner: nil) as? NSTableCellView else { return nil }
        cell.textField?.stringValue = text
        
        return cell;
    }
    
    func tableViewSelectionDidChange(_ notification: Notification) {
        guard let tbl = notification.object as? NSTableView else { return }
        if tbl.selectedRow >= devices.count ||
           tbl.selectedRow < 0 {
            return
        }
        
        let ad = NSApplication.shared.delegate as! AppDelegate
        let device = devices[tbl.selectedRow]
        
        ad.conntectionType = device.interfaceType.rawValue
        ad.deviceName = device.name
        ad.networkDevice = nil
        
        switch device.interfaceType {
        case .WIFI: fallthrough
        case .ETHERNET:
            ad.connectionString = String(format:"%@:%@", device.address, device.portNumber)
            ad.networkDevice = device
        case .BLUETOOTH: fallthrough
        case .BLE:
            ad.connectionString = String(format:"%@", device.macAddress)
        case .USB:
            ad.connectionString = device.address
        default:
            ad.connectionString = "Unknown"
        }
    }
}
