//
//  AppState.swift
//  cmbSDKToolkitSample
//
//

import SwiftUI
import Foundation
import cmbSDK
import Combine

class ReaderManager: NSObject, CMBReaderDeviceDelegate, ObservableObject {
    
    var readerDevice: CMBReaderDevice?
    private var peripheralUUID: UUID?
    let readerState = ReaderState()
    var subscribers = [AnyCancellable]()

    override init() {
        super.init()
        self.subscribeToChanges()
    }
    
    func subscribeToChanges() {
        self.subscribers.append(self.readerState.readerConfig.$beepOnSuccess.sink(receiveValue: { newValue in
                self.readerDevice?.dataManSystem().sendCommand("SET BEEPER.ENABLED \(newValue ? "ON" : "OFF")")
        }))
        self.subscribers.append(self.readerState.readerConfig.$showImage.sink(receiveValue: { newValue in
            self.readerDevice?.imageResultEnabled = newValue
        }))
    }
    
    deinit {
        self.disconnect()
    }
    
    func connect(peripheralUUID: UUID) {
        self.resetReaderState()
        if peripheralUUID != self.peripheralUUID || self.readerDevice?.connectionState != CMBConnectionStateConnected {
            self.disconnect()
            self.readerDevice = CMBReaderDevice.reader(ofBluetoothPeripheralUUID: peripheralUUID, psm: CBL2CAPPSM(192))
            self.peripheralUUID = peripheralUUID
            self.readerDevice?.delegate = self
            self.readerDevice?.connect()
        }
    }
    
    private func disconnect() {
        self.readerDevice?.delegate = nil
        self.readerDevice?.disconnect()
        self.readerDevice = nil
        self.peripheralUUID = nil
        self.resetReaderState()
    }
    
    func resetReaderState() {
        self.readerState.connectionState = CMBConnectionStateDisconnected
        self.readerState.readResult = nil
    }
    
    func connectionStateDidChange(ofReader reader: CMBReaderDevice) {
        self.readerState.connectionState = reader.connectionState
        print("ConnectionState: \(self.readerState.connectionState)")
        if reader.connectionState == CMBConnectionStateConnected {
            self.updateReaderConfig()
            self.setImageQuality()
            self.readerState.readerConfig.showImage = true
        }
    }
    
    func setImageQuality() {
        self.readerDevice?.dataManSystem().sendCommand("SET IMAGE.FORMAT 1") // JPEG
        self.readerDevice?.dataManSystem().sendCommand("SET IMAGE.QUALITY 50")
        self.readerDevice?.dataManSystem().sendCommand("SET IMAGE.SIZE 2") // 1/16
    }
    
    func updateReaderConfig() {
        if self.readerState.connectionState == CMBConnectionStateConnected {
            self.readerState.readerConfig.showImage = self.readerDevice?.imageResultEnabled ?? false
            self.readerDevice?.dataManSystem().sendCommand("GET BEEPER.ENABLED", withCallback: { response in
                self.readerState.readerConfig.beepOnSuccess = (response.payload == "ON")
            })
        }
    }
    
    func didReceiveReadResult(fromReader reader: CMBReaderDevice, results readResults: CMBReadResults) {
        
        let firstResult = readResults.readResults.first
        if firstResult != nil, firstResult!.goodRead {
            self.readerState.readResult = firstResult
        }
    }
}
