package com.zj365.mime.act

import android.bluetooth.BluetoothManager
import android.content.Context
import android.content.Intent
import android.location.LocationManager
import android.os.Build
import android.provider.Settings
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.android.arouter.facade.annotation.Route
import com.xty.base.act.BaseVmAct
import com.xty.common.LogUtils
import com.xty.common.arouter.ARouterUrl
import com.xty.common.bracelet.*
import com.xty.common.recycleUtils.RecycleItem
import com.xty.common.util.CommonToastUtils
import com.zj365.mime.R
import com.zj365.mime.adapter.DebugDevAdapter
import com.zj365.mime.databinding.ActDebugBinding
import com.zj365.mime.vm.DebugVm
import com.zj365.mime.weight.NoticeSettingDialog
import com.yucheng.ycbtsdk.YCBTClient
import com.yucheng.ycbtsdk.bean.ScanDeviceBean
import java.io.BufferedReader
import java.io.InputStreamReader
import java.text.SimpleDateFormat
import java.util.*

/**
 * 调试页面
 */
@Route(path = ARouterUrl.DEBUG)
class DebugAct : BaseVmAct<DebugVm>() {

    val binding by lazy { ActDebugBinding.inflate(layoutInflater) }

    //传统蓝牙 初始化
    private val bluetoothManager by lazy { getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager }
    private val blueAdapter by lazy { bluetoothManager.adapter }
    val adapter by lazy { DebugDevAdapter() }
    var bean = ScanDeviceBean()

    private var mReader: BufferedReader? = null
    private var sb = StringBuilder()
    private var mLogcatProc: Process? = null


    override fun setLayout() = binding.root

    override fun initData() {
        super.initData()
        isDarkBar = true
    }

    override fun initView() {
        super.initView()
        statusBar(binding.title.mView)
        binding.title.mTvTitle.text = "调试模式"
        binding.title.mIvBack.setOnClickListener {
            finish()
        }

        initAdapter()

        thread.start()

        binding.tvFirst.setOnClickListener(onClickListener)
        binding.tvSecond.setOnClickListener(onClickListener)
        binding.tvThird.setOnClickListener(onClickListener)
        binding.tvFour.setOnClickListener(onClickListener)
        binding.tvFive.setOnClickListener(onClickListener)
        binding.mSubmit.setOnClickListener(onClickListener)
        binding.tvSix.setOnClickListener(onClickListener)
    }


    private var thread = Thread {
        try {
            mLogcatProc = Runtime.getRuntime().exec("logcat $packageName:D")
            mReader = BufferedReader(InputStreamReader(mLogcatProc?.inputStream))

            var line: String?

            while ((mReader!!.readLine().also { line = it }) != null) {
                sb.append("\n$line")
                if (sb.length > 2000) {
                    Thread.sleep(500)
                    mViewModel.upload(sb.toString())
                    sb.clear()
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            try {
                mViewModel.upload(sb.toString())
                if (mReader != null) {
                    mReader!!.close()
                    mReader = null
                }
                if (mLogcatProc != null) {
                    mLogcatProc!!.destroy()
                    mLogcatProc = null
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }


    private fun initAdapter() {
        adapter.macAddress = ""
        binding.mRecycle.addItemDecoration(RecycleItem(this, 10))
        binding.mRecycle.layoutManager = LinearLayoutManager(this)
        binding.mRecycle.adapter = adapter
        adapter.setOnItemClickListener { a, view, position ->
            bean = a.getItem(position) as ScanDeviceBean
            closeBlueSearch()
            binding.mResult.text = "已选择蓝牙：${bean.deviceName}"
            mViewModel.uploadLog(binding.mResult.text.toString())
        }
    }

    private val onClickListener = View.OnClickListener {
        when (it.id) {
            R.id.tv_first -> {//蓝牙搜索
                binding.mRecycle.visibility = View.VISIBLE
                var boolean = YCBBlueConnectHelper.getBlueStatus(false)
                if (boolean) {
                    YCBBlueConnectHelper.disconnect()
                }
                startBlueSearch()
            }
            R.id.tv_six -> {
                LogUtils.d("SDK 蓝牙搜索开启！")
                binding.mResult.text = "开始搜索蓝牙设备（SDK）"
                binding.mRecycle.visibility = View.VISIBLE
                var boolean = YCBBlueConnectHelper.getBlueStatus(false)
                if (boolean) {
                    YCBBlueConnectHelper.disconnect()
                }
                YCBBlueConnectHelper.scanBlueTooth {
                    LogUtils.d("SDK蓝牙扫描设备名：${it.deviceName}；Mac地址:${it.deviceMac}")
                    adapter.data.forEach { listChild ->
                        //筛选重复的蓝牙设备
                        if (listChild.deviceName == it.deviceName) {
                            return@forEach
                        }
                    }

                    var scanDeviceBean = ScanDeviceBean()
                    scanDeviceBean.deviceName = it.deviceName
                    scanDeviceBean.deviceMac = it.deviceMac
                    scanDeviceBean.deviceRssi = it.deviceRssi//信号强度,暂时不需要
                    adapter.addData(scanDeviceBean)
                }
            }
            R.id.tv_second -> {//蓝牙连接

                if (!blueAdapter.isEnabled) {
                    CommonToastUtils.showToast("请先打开蓝牙！")
                    return@OnClickListener
                }

                binding.mRecycle.visibility = View.GONE
                if (null == bean || bean.deviceMac.isNullOrEmpty()) {
                    CommonToastUtils.showToast("请先选择需要连接的蓝牙！")
                    return@OnClickListener
                }

                YCBBlueConnectHelper.connectionBlueTooth(bean.deviceMac, true) { connectState ->
                    when (connectState) {
                        YCBBlueConnectHelper.BLEConnectState.Connected -> {
                            updateResultText("${bean.deviceName};${bean.deviceMac}蓝牙连接成功")
                        }

                        YCBBlueConnectHelper.BLEConnectState.Connecting -> {
                            updateResultText("${bean.deviceName};${bean.deviceMac}蓝牙正在连接")
                        }

                        YCBBlueConnectHelper.BLEConnectState.DisConnect -> {
                            updateResultText("${bean.deviceName};${bean.deviceMac}蓝牙未连接")
                        }
                    }
                }
            }
            R.id.tv_third -> {//设备信息获取
                binding.mRecycle.visibility = View.GONE
                YCBManager.getDeviceInfo { isok, value ->
                    if (isok) {
                        updateResultText(value)
                    } else {
                        updateResultText("设备信息获取失败")
                    }
                }
            }
            R.id.tv_four -> {//蓝牙连接状态获取
                binding.mRecycle.visibility = View.GONE
                var boolean = YCBBlueConnectHelper.getBlueStatus(false)
                var connectState = YCBTClient.connectState()
                updateResultText("是否连接：$boolean;;连接状态:$connectState;;")
            }
            R.id.tv_five -> {//蓝牙权限检查
                binding.mRecycle.visibility = View.GONE
                getBluePermission(baseContext){
                    if (it){
                        updateResultText("已同意所有蓝牙权限")
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //如果Android 系统6.0以上
                            if (!checkGPSIsOpen()) {//GPS未打开
                                requestGPSPermission()
                            }
                        }
                    }else{
                        updateResultText("缺少蓝牙权限")
                    }
                }
                var connectPer = checkBlueConnectPermission(baseContext)
                println("连接：$connectPer")
                var gpsOpen = checkGPSIsOpen()
                println("GPS：$gpsOpen")
            }

            R.id.mSubmit -> {//只上传蓝牙搜索列表数据
                upload()
            }
        }
    }


    /**
     * 开启蓝牙搜索
     */
    private fun startBlueSearch() {
        if (!checkBlueConnectPermission(baseContext)) {
            CommonToastUtils.showToast("请开启App蓝牙搜索权限！")
            return
        }

        if (null == blueAdapter) {
            CommonToastUtils.showToast("蓝牙搜索异常，请退出App后重试！")
            return
        }

        if (null == blueAdapter.bluetoothLeScanner) {
            CommonToastUtils.showToast("蓝牙搜索异常，请退出重试！")
            return
        }

        if (!blueAdapter.isEnabled) {
            CommonToastUtils.showToast("请开启蓝牙！")
            return
        }

        binding.mResult.text = "开始搜索蓝牙设备"

        blueAdapter.startDiscovery();  //启动扫描蓝牙任务

        //开始扫描蓝牙设备
        blueAdapter.bluetoothLeScanner.startScan(scanCallBack)
    }

    /**
     * 关闭蓝牙搜索
     */
    private fun closeBlueSearch() {

        if (!checkBlueConnectPermission(baseContext)) {
            LogUtils.d("没有蓝牙权限...")
            return
        }

        if (null == blueAdapter) {
            LogUtils.d("蓝牙适配器为空!")
            return
        }

        if (null == blueAdapter.bluetoothLeScanner) {
            LogUtils.d("蓝牙扫描仪为空!")
            return
        }

        if (null == scanCallBack) {
            LogUtils.d("scanCallBack is Null!")
            return
        }


        LogUtils.d("开始关闭蓝牙扫描...")
        blueAdapter.cancelDiscovery()
        blueAdapter.bluetoothLeScanner.stopScan(scanCallBack)
        LogUtils.d("关闭蓝牙扫描完成...")
    }

    private var scanCallBack = MyScanCallback { deviceName, address ->
        LogUtils.d("蓝牙扫描设备名：$deviceName；Mac地址:$address")
        if (!deviceName.startsWith("U32")){
            return@MyScanCallback
        }
        adapter.data.forEach { listChild ->
            //筛选重复的蓝牙设备
            if (listChild.deviceName == deviceName) {
                return@MyScanCallback
            }
            //筛选非手表设备

        }

        var scanDeviceBean = ScanDeviceBean()
        scanDeviceBean.deviceName = deviceName
        scanDeviceBean.deviceMac = address
        scanDeviceBean.deviceRssi = 0//信号强度,暂时不需要

        adapter.addData(scanDeviceBean)
    }

    val reqGpsPermissionDialog by lazy {
        NoticeSettingDialog(this, "请打开GPS权限",{

        }){
            // 转到手机设置界面，用户设置GPS
            var intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivityForResult(intent, 0); // 设置完成后返回到原来的界面
        }
    }


    private fun requestGPSPermission(){
        reqGpsPermissionDialog.show()
    }

    private fun checkGPSIsOpen(): Boolean {
        val locationManager = this.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
    }

    /**
     * 输出手机系统信息
     */
    private fun printSystemInfo(): String {
        var date = Date(System.currentTimeMillis())
        var dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        var time = dateFormat.format(date)
        var sb = StringBuilder()
        sb.append("_______  系统信息  ").append(time).append(" ______________")
        sb.append("\nID                 :").append(Build.ID)
        sb.append("\nBRAND              :").append(Build.BRAND)
        sb.append("\nMODEL              :").append(Build.MODEL)
        sb.append("\nRELEASE            :").append(Build.VERSION.RELEASE)
        sb.append("\nSDK                :").append(Build.VERSION.SDK)

        sb.append("\n_______ OTHER _______")
        sb.append("\nBOARD              :").append(Build.BOARD)
        sb.append("\nPRODUCT            :").append(Build.PRODUCT)
        sb.append("\nDEVICE             :").append(Build.DEVICE)
        sb.append("\nFINGERPRINT        :").append(Build.FINGERPRINT)
        sb.append("\nHOST               :").append(Build.HOST)
        sb.append("\nTAGS               :").append(Build.TAGS)
        sb.append("\nTYPE               :").append(Build.TYPE)
        sb.append("\nTIME               :").append(Build.TIME)
        sb.append("\nINCREMENTAL        :").append(Build.VERSION.INCREMENTAL)

        sb.append("\n_______ CUPCAKE-3 _______")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
            sb.append("\nDISPLAY            :").append(Build.DISPLAY)
        }

        sb.append("\n_______ DONUT-4 _______")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT) {
            sb.append("\nSDK_INT            :").append(Build.VERSION.SDK_INT)
            sb.append("\nMANUFACTURER       :").append(Build.MANUFACTURER)
            sb.append("\nBOOTLOADER         :").append(Build.BOOTLOADER)
            sb.append("\nCPU_ABI            :").append(Build.CPU_ABI)
            sb.append("\nCPU_ABI2           :").append(Build.CPU_ABI2)
            sb.append("\nHARDWARE           :").append(Build.HARDWARE)
            sb.append("\nUNKNOWN            :").append(Build.UNKNOWN)
            sb.append("\nCODENAME           :").append(Build.VERSION.CODENAME)
        }

        sb.append("\n_______ GINGERBREAD-9 _______")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
            sb.append("\nSERIAL             :").append(Build.SERIAL)
        }
        return sb.toString()
    }

    private var showToast = false
    private fun upload() {
        var searchBlueData = StringBuilder()
        adapter.data.forEach {
            searchBlueData.append("MacAddress:${it.deviceMac};BlueName:${it.deviceName}")
        }

        if (searchBlueData.isNotEmpty()) {
            mViewModel.uploadLog(searchBlueData.toString())
        }
        mViewModel.uploadLog(printSystemInfo())
    }

    private fun updateResultText(result: String) {
        showToast = true
        binding.mResult.text = result
        mViewModel.uploadLog(result.toString())
    }

    override fun liveObserver() {
        mViewModel.uploadLive.observe(this) {
            if (showToast) {
                CommonToastUtils.showSucceedToast("操作已完成")
            }
        }
    }

    override fun onDestroy() {
        if (mLogcatProc != null) {
            mLogcatProc!!.destroy()
            mLogcatProc = null
        }
        super.onDestroy()
    }
}