package com.dlc.chemical.ui.settings

import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.dlc.chemical.R
import com.dlc.chemical.databinding.ActivitySettingsSteelyardBinding
import com.dlc.chemical.sp.UsbDevicesSp
import com.hoho.android.usbserial.driver.CdcAcmSerialDriver
import com.hoho.android.usbserial.driver.ProbeTable
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber
import com.rc.core.ui.activity.RcBaseActivity
import java.util.*

/**
 * info
 *
 * @author ReiChin_
 */
class SteelyardSettingsActivity : RcBaseActivity<ActivitySettingsSteelyardBinding>() {

    override fun createViewBinding() = ActivitySettingsSteelyardBinding.inflate(layoutInflater)

    private val mAdapter by lazy { UsbDevicesAdapter() }

    override fun initViews(savedInstanceState: Bundle?) {
        viewBinding.back.setOnClickListener {
            finish()
        }

        viewBinding.swipeRefreshLayout.setOnRefreshListener { loadData() }

        mAdapter.setOnItemClickListener { _, _, position ->
            val item = mAdapter.getItem(position)
            if (null == item.driver) {
                showToast("no driver")
                return@setOnItemClickListener
            }

            UsbDevicesSp.saveConfig(
                context = this,
                vendorId = item.device.vendorId,
                productId = item.device.productId
            )
            viewBinding.recyclerView.postDelayed({
                setResult(RESULT_OK)
                finish()
            }, 50)
        }
        mAdapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInBottom)
        viewBinding.recyclerView.layoutManager = LinearLayoutManager(this)
        createItemDecoration()?.let { viewBinding.recyclerView.addItemDecoration(it) }
        viewBinding.recyclerView.adapter = mAdapter
    }

    override fun initData() {
        loadData()
    }

    private fun loadData() {
        val listItems = mutableListOf<ListItem>()

        val usbDefaultProber: UsbSerialProber = UsbSerialProber.getDefaultProber()
        val usbCustomProber: UsbSerialProber = CustomProber.getCustomProber()

        val usbManager: UsbManager = getSystemService(USB_SERVICE) as UsbManager
        usbManager.deviceList.values.forEach { device ->
            val driver = usbDefaultProber.probeDevice(device) ?: usbCustomProber.probeDevice(device)
            if (null == driver) {
                listItems.add(ListItem(device, 0, null))
            } else {
                for (port in driver.ports.indices)
                    listItems.add(ListItem(device, port, driver)
                )
            }
        }
        mAdapter.setNewInstance(listItems)
        if (listItems.isEmpty()) {
            mAdapter.setEmptyView(R.layout.view_list_empty)
        }
    }

}

private class UsbDevicesAdapter :
    BaseQuickAdapter<ListItem, BaseViewHolder>(R.layout.item_usb_devices) {

    override fun convert(holder: BaseViewHolder, item: ListItem) {
        holder.setText(R.id.text1, formatText1(item))
            .setText(R.id.text2, formatText2(item.device))
    }

    private fun formatText1(item: ListItem): String {
        if (null == item.driver) return "<no driver>"
        if (item.driver.ports.size == 1) return item.driver.javaClass.simpleName.replace(
            "SerialDriver",
            ""
        )
        return item.driver.javaClass.simpleName.replace("SerialDriver", "") + ", Port${item.port}"
    }

    private fun formatText2(device: UsbDevice): String {
        return String.format(
            Locale.US,
            "Vendor %04X, Product %04X, deviceName %s",
            device.vendorId,
            device.productId,
            device.deviceName
        )
    }

}

data class ListItem(val device: UsbDevice, val port: Int, val driver: UsbSerialDriver?)

object CustomProber {

    fun getCustomProber(): UsbSerialProber {
        val customTable = ProbeTable()
        customTable.addProduct(0x16d0, 0x087e, CdcAcmSerialDriver::class.java) // e.g. Digispark CDC
        return UsbSerialProber(customTable)
    }
}