package com.reactnativerfidble.adapters

import android.os.Handler
import com.facebook.react.bridge.ReactApplicationContext
import com.reactnativerfidble.generic.RfidBleGenericEpcReply
import com.reactnativerfidble.generic.RfidBleGenericReader
import com.reactnativerfidble.toHexString
import com.reader.ble.BU01_Factory
import com.reader.ble.BU01_Reader

class RfidBleBU01Adapter(
    private val reactContext: ReactApplicationContext
) : RfidBleAdapter(reactContext) {
    companion object {
        /**
         * This is a magic number. I don't know if this delay is the correct one
         * but it works correctly on my experiments.
         *
         * Feel free to increment or decrement this.
         */
        const val SINGLE_INVENTORY_DELAY = 400L
    }

    private var readerConnected: BU01_Reader? = null
    private val singleInventoryHandler = Handler(reactContext.mainLooper)

    private val singleInventoryRunnable = Runnable {
        executeSingleInventory()
    }

    override fun connectToReader(readerAddress: String) {
        val foundReader =
            BU01_Factory.bu01ByAddress(reactContext, readerAddress)

        val genericReader = RfidBleGenericReader(foundReader.name, foundReader.address)

        foundReader.connect(reactContext, object : BU01_Reader.Callback {
            override fun onConnect() {
                readerConnected = foundReader
                emitBleReaderEvent(RfidEvent.READER_CONNECTED, genericReader)
                singleInventoryHandler.post(singleInventoryRunnable)
            }

            override fun onDisconnect() {
                readerConnected = null
                singleInventoryHandler.removeCallbacks(singleInventoryRunnable)
                emitBleReaderEvent(RfidEvent.READER_DISCONNECTED, genericReader)
            }
        })
    }

    override fun disconnect() {
        readerConnected?.disconnect()
    }

    private fun executeSingleInventory() {
        readerConnected?.singleInventory { status, list ->
            if (status == 0 && list.isNotEmpty()) {
                emitBleEpcReplies(
                    "BU01",
                    list,
                    fun(reply) = RfidBleGenericEpcReply(reply.epc.toHexString())
                )
            }
        }

        singleInventoryHandler.postDelayed(
            singleInventoryRunnable,
            SINGLE_INVENTORY_DELAY
        )
    }
}