package com.grkj.iscs.view.activity.test

import android.app.Activity
import android.bluetooth.BluetoothGatt
import android.content.Intent
import android.os.Build
import android.util.Log
import com.clj.fastble.BleManager
import com.clj.fastble.data.BleDevice
import com.clj.fastble.exception.BleException
import com.grkj.iscs.BusinessManager
import com.grkj.iscs.R
import com.grkj.iscs.view.base.BaseActivity
import com.grkj.iscs.ble.BleBean
import com.grkj.iscs.ble.BleCmdManager
import com.grkj.iscs.ble.BleConst.INDICATE_UUID
import com.grkj.iscs.ble.BleConst.SERVICE_UUID
import com.grkj.iscs.ble.BleConst.STATUS_READY
import com.grkj.iscs.ble.BleConst.STATUS_WORK
import com.grkj.iscs.ble.BleUtil
import com.grkj.iscs.ble.CustomBleGattCallback
import com.grkj.iscs.ble.CustomBleIndicateCallback
import com.grkj.iscs.ble.CustomBleScanCallback
import com.grkj.iscs.ble.CustomBleWriteCallback
import com.grkj.iscs.databinding.ActivityBleBinding
import com.grkj.iscs.extentions.toHexStrings
import com.grkj.iscs.model.Constants.BLE_LOCAL_NAME
import com.grkj.iscs.model.Constants.PERMISSION_REQUEST_CODE
import com.grkj.iscs.util.CommonUtils
import com.grkj.iscs.util.Executor
import com.grkj.iscs.util.ToastUtils
import com.grkj.iscs.util.log.LogUtil
import com.leon.lfilepickerlibrary.LFilePicker
import com.zhy.adapter.recyclerview.CommonAdapter
import com.zhy.adapter.recyclerview.base.ViewHolder
import pub.devrel.easypermissions.AfterPermissionGranted
import java.io.File

class BleActivity : BaseActivity<ActivityBleBinding>() {

    private val FILE_CODE = 1000
    private var fileMac: String? = null
    // TODO 重新指向数据，但是调试完必须重启防止数据干扰
    var mBleList: MutableList<BleBean> = BusinessManager.deviceList

    override val viewBinding: ActivityBleBinding
        get() = ActivityBleBinding.inflate(layoutInflater)

    override fun initView() {
        mBleList.clear()
        BleManager.getInstance().disconnectAllDevice()
        mBinding?.srl?.setEnableRefresh(true)
        mBinding?.srl?.setEnableLoadMore(false)
        mBinding?.srl?.autoRefresh()
        mBinding?.srl?.setOnRefreshListener {
            CommonUtils.checkBlePermission(this) {
                doScan()
            }
        }

        mBinding?.rvBle?.adapter =
            object : CommonAdapter<BleBean>(this, R.layout.item_ble, mBleList) {
                override fun convert(holder: ViewHolder, item: BleBean?, position: Int) {
                    holder.setText(R.id.ble_name, "Name：${item?.bleDevice?.name}")
                    holder.setText(R.id.ble_mac, "Mac：${item?.bleDevice?.mac}")
                    holder.setText(R.id.blc_connection, if (BleManager.getInstance().isConnected(item?.bleDevice)) "已连接" else "未连接")
                    holder.setOnClickListener(R.id.connect) { doConnect(position) }
                    holder.setOnClickListener(R.id.disconnect) {
                        BleUtil.instance?.indicate(mBleList[position].bleDevice, isStart = false, indicateCallback = null)
                        BleManager.getInstance().disconnect(item?.bleDevice)
                        Executor.delayOnMain(200) {
                            mBinding?.rvBle?.adapter?.notifyItemChanged(position)
                        }
                    }

                    holder.setOnClickListener(R.id.mtu) {
                        BleUtil.instance?.setMtu(mBleList[position].bleDevice)
                    }

                    holder.setOnClickListener(R.id.indicate) {
                        item?.let {
                            BleUtil.instance?.indicate(it.bleDevice, indicateCallback = object : CustomBleIndicateCallback() {
                                override fun onPrompt(promptStr: String?) {
                                    LogUtil.i("监听onPrompt ： $promptStr")
                                }

                                override fun onConnectPrompt(promptStr: String?) {
                                    LogUtil.i("监听onConnectPrompt ： $promptStr")
                                }

                                override fun onDisConnectPrompt(promptStr: String?) {
                                    LogUtil.i("监听onDisConnectPrompt ： $promptStr")
                                }

                                override fun onIndicateSuccess() {
                                    LogUtil.i("监听成功")
                                }

                                override fun onIndicateFailure(exception: BleException?) {
                                    LogUtil.i("监听失败")
                                }

                                override fun onCharacteristicChanged(data: ByteArray?) {
                                    LogUtil.i("******************* : ${data?.toHexStrings()}")
                                    data?.let { itData ->
                                        BleCmdManager.handleRsp(it, itData)
                                    }
                                }
                            })
                        }
                    }

                    holder.setOnClickListener(R.id.stopIndicate) {
                        item?.let {
                            BleUtil.instance?.indicate(it.bleDevice, isStart = false, indicateCallback = null)
                        }
                    }

                    holder.setOnClickListener(R.id.exit) { finish() }

                    holder.setOnClickListener(R.id.token) {
                        BleCmdManager.getToken(item?.bleDevice?.mac, object : CustomBleWriteCallback() {
                            override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
                                LogUtil.i("getToken success")
                            }

                            override fun onWriteFailure(exception: BleException?) {
                                LogUtil.e("getToken fail")
                            }
                        })
                    }

                    holder.setOnClickListener(R.id.version) {
                        BleCmdManager.getVersion(item?.bleDevice?.mac, object : CustomBleWriteCallback() {
                            override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
                                LogUtil.i("getVersion success")
                            }

                            override fun onWriteFailure(exception: BleException?) {
                                LogUtil.e("getVersion fail")
                            }
                        })
                    }

                    holder.setOnClickListener(R.id.power) {
                        BleCmdManager.getPower(item?.bleDevice?.mac, object : CustomBleWriteCallback() {
                            override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
                                LogUtil.i("getPower success")
                            }

                            override fun onWriteFailure(exception: BleException?) {
                                LogUtil.e("getPower fail")
                            }
                        })
                    }

                    holder.setOnClickListener(R.id.device) {
                        BleCmdManager.getCurrentStatus(item?.bleDevice!!, object : CustomBleWriteCallback() {
                            override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
                                LogUtil.i("getCurrentStatus success")
                            }
                            override fun onWriteFailure(exception: BleException?) {
                                LogUtil.e("getCurrentStatus fail")}
                        })
                    }

                    holder.setOnClickListener(R.id.work_mode) {
                        BleCmdManager.switchMode(STATUS_WORK, item?.bleDevice!!, object : CustomBleWriteCallback() {
                            override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
                                LogUtil.i("switch mode work success")}
                            override fun onWriteFailure(exception: BleException?) {
                                LogUtil.i("switch mode work fail")}
                        })
                    }

                    holder.setOnClickListener(R.id.standby_mode) {
                        BleCmdManager.switchMode(STATUS_READY, item?.bleDevice!!, object : CustomBleWriteCallback() {
                            override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
                                LogUtil.i("switch mode ready success")}
                            override fun onWriteFailure(exception: BleException?) {
                                LogUtil.e("switch mode ready fail")}
                        })
                    }

                    holder.setOnClickListener(R.id.ticketStatus) {
                        BleCmdManager.getTicketStatus(item?.bleDevice!!, object : CustomBleWriteCallback() {
                            override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
                                LogUtil.i("getTicketStatus success")}
                            override fun onWriteFailure(exception: BleException?) {
                                LogUtil.e("getTicketStatus fail")}
                        })
                    }

                    // 上锁工作票
                    holder.setOnClickListener(R.id.sendTicket) {
                        val testStr = "{\"cardNo\":\"267747D5\",\"data\":[{\"codeId\":1,\"dataList\":[{\"dataId\":17,\"equipName\":\"E-17\",\"equipRfidNo\":\"1DCAD26D031080\",\"target\":0},{\"dataId\":18,\"equipName\":\"E-18\",\"equipRfidNo\":\"1DA0C66D031080\",\"target\":0}],\"taskCode\":\"243\"}],\"lockList\":[{\"lockId\":1,\"rfid\":\"0089D495\"},{\"lockId\":2,\"rfid\":\"B05AD495\"}],\"password\":\"123456\"}"
                        BleCmdManager.sendWorkTicket(testStr, bleDevice = item?.bleDevice!!, callback = object : CustomBleWriteCallback() {
                            override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
                                LogUtil.i("sendTicket lock success")
                            }

                            override fun onWriteFailure(exception: BleException?) {
                                LogUtil.e("sendTicket lock fail")
                            }
                        })
                    }

                    // 解锁工作票
                    holder.setOnLongClickListener(R.id.sendTicket) {
                        val testStr = "{\"cardNo\":\"267747D5\",\"data\":[{\"codeId\":1,\"dataList\":[{\"dataId\":17,\"equipName\":\"E-17\",\"equipRfidNo\":\"1DCAD26D031080\",\"target\":1,\"infoRfidNo\":\"0089D495\"},{\"dataId\":18,\"equipName\":\"E-18\",\"equipRfidNo\":\"1DA0C66D031080\",\"target\":1,\"infoRfidNo\":\"B05AD495\"}],\"taskCode\":\"243\"}],\"password\":\"123456\"}"
                        BleCmdManager.sendWorkTicket(testStr, bleDevice = item?.bleDevice!!, callback = object : CustomBleWriteCallback() {
                            override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
                                LogUtil.i("sendTicket unlock success")
                            }

                            override fun onWriteFailure(exception: BleException?) {
                                LogUtil.e("sendTicket unlock fail")
                            }
                        })
                        return@setOnLongClickListener true
                    }

                    holder.setOnClickListener(R.id.sendFile) {
                        fileMac = item?.bleDevice?.mac

                        LFilePicker()
                            .withActivity(this@BleActivity)
                            .withRequestCode(FILE_CODE)
//                            .withStartPath("${FileUtil.getRootFolder(this)?.absolutePath}")
                            .start()

                    }
                }
            }

        BleManager.getInstance().init(application)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            FILE_CODE -> {
                if (resultCode == Activity.RESULT_OK && data != null) {
                    val list: List<String>? = data.getStringArrayListExtra("paths")
                    LogUtil.d("选择的文件为: $list")
                    if (list.isNullOrEmpty()) {
                        ToastUtils.tip("请选择文件!")
                        return
                    }
                    BleCmdManager.sendFile(2, File(list[0]), mac = fileMac, callback = object : CustomBleWriteCallback() {
                        override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
                            LogUtil.i("sendFile success")
                        }

                        override fun onWriteFailure(exception: BleException?) {
                            LogUtil.e("sendFile fail")
                        }
                    })
                }
            }
        }
    }

    @AfterPermissionGranted(PERMISSION_REQUEST_CODE)
    fun doScan() {
        Log.d("doScanBle", "扫描开始：$")
        BleUtil.instance?.scan(object : CustomBleScanCallback() {
            override fun onPrompt(promptStr: String?) {
                ToastUtils.tip(promptStr)
                mBinding?.srl?.finishRefresh()
                BleManager.getInstance().enableBluetooth()
            }

            override fun onScanStarted(success: Boolean) {
                Log.d("doScanBle", "扫描开始：${success}")
                mBleList.clear()
                mBinding?.rvBle?.adapter?.notifyDataSetChanged()
            }

            override fun onScanning(bleDevice: BleDevice?) {
                bleDevice?.let {
                    Log.d("doScanBle", "扫描到的设备：${it.mac}")
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                        if (!it.name.isNullOrBlank() && it.name == BLE_LOCAL_NAME) {
                            mBleList.add(BleBean(it))
                            mBinding?.rvBle?.adapter?.notifyDataSetChanged()
                        } else {

                        }
                    } else {
                        mBleList.add(BleBean(it))
                        mBinding?.rvBle?.adapter?.notifyDataSetChanged()
                    }
                }
            }

            override fun onScanFinished(scanResultList: MutableList<BleDevice>?) {
                mBinding?.srl?.finishRefresh()
                if (mBleList.isEmpty()) {
                    ToastUtils.tip("没有扫描到设备，请下拉刷新重试！")
                }
            }
        })
    }

    fun doConnect(position: Int) {
        handleLoading(true)
        BleManager.getInstance().disconnect(mBleList[position].bleDevice)
        BleUtil.instance?.connectBySelect(mBleList[position].bleDevice,
            object : CustomBleGattCallback() {
                override fun onPrompt(promptStr: String?) {
                    handleLoading(false)
                    ToastUtils.tip(promptStr)
                }

                override fun onStartConnect() {
                }

                override fun onConnectFail(bleDevice: BleDevice?, exception: BleException?) {
                    handleLoading(false)
                    ToastUtils.tip("连接失败，请重试！")
                }

                override fun onConnectSuccess(
                    bleDevice: BleDevice?,
                    gatt: BluetoothGatt?,
                    status: Int
                ) {
                    handleLoading(false)
                    LogUtil.i("onConnectSuccess : ${bleDevice?.mac}")
                    bleDevice?.let {
                        mBinding?.rvBle?.adapter?.notifyItemChanged(position)
                        LogUtil.i("Add BleBean : $mBleList")
                    }
                }

                override fun onDisConnected(
                    isActiveDisConnected: Boolean,
                    device: BleDevice?,
                    gatt: BluetoothGatt?,
                    status: Int
                ) {
                    LogUtil.i("onDisConnected : ${device?.mac} - $isActiveDisConnected")
                    handleLoading(false)
                    ToastUtils.tip("连接断开了，请重试！")
                    mBinding?.rvBle?.adapter?.notifyItemChanged(position)
//                    mBleList.removeAt(position)
                }
            })
    }

    override fun onDestroy() {
        super.onDestroy()

        mBleList.forEach {
            BleManager.getInstance().stopIndicate(it.bleDevice, SERVICE_UUID, INDICATE_UUID)
        }
        mBleList.clear()
        BleManager.getInstance().disconnectAllDevice()
    }
}