package com.xhly.manageapp.service.websocket

import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.widget.Toast
import com.billbook.lib.downloader.Download
import com.billbook.lib.downloader.Downloader
import com.xhly.corelib.Const
import com.xhly.corelib.bean.AppInfo
import com.xhly.corelib.eventbus.UIEvent
import com.xhly.corelib.network.RetrofitService
import com.xhly.corelib.utils.AppUtils
import com.xhly.corelib.utils.GsonUtils
import com.xhly.corelib.utils.LogShow
import com.xhly.corelib.utils.MD5Utils
import com.xhly.corelib.utils.SharedPreferencesUtils
import com.xhly.manageapp.ManageApplication
import com.xhly.manageapp.bean.EventLog
import com.xhly.manageapp.bean.log.LogAppStartBean
import com.xhly.manageapp.bean.log.LogdOperateBean
import com.xhly.manageapp.network.log.LogService
import com.xhly.websocket.bean.WebSocketData
import com.xhly.websocket.bean.WebSocketUserBean
import com.xhly.websocket.service.SocketClient
import com.xhly.websocket.service.WebSocketHelper
import com.xhly.websocket.utils.SocketPushUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.File
import java.util.UUID

class AppSocket : SocketClient() {
    var logService = RetrofitService.create<LogService>()
    private val serviceScope = CoroutineScope(MainScope().coroutineContext)
    private var appList = arrayListOf<AppInfo>()


    val spUtils by lazy { SharedPreferencesUtils.getInstance(context) }

    companion object {
        //标记上次打开的包名，当连续打开同一包名时，不认为打开多次
        var lastPkgName = ""
    }

    override fun startSocket(context: Context?) {
        EventBus.getDefault().register(this)
        connectUrl = Const.WSURL
        /* startNotification()*/
        LogShow("已经创建")
        appList = AppUtils.GetAppList(context) as ArrayList<AppInfo>
        //downLoadFile("")
        super.startSocket(context)
    }

    override fun processTextMessage(text: String) {
        //Log.v("websocket收到的消息", text);
        SocketPushUtils.dealPushMessage(text)
    }

    override fun onConnectedSuccess() {
        super.onConnectedSuccess()
        UIEvent(Const.UPDATE_CONNECTED_SUCCESS).post()
        val webData = WebSocketData()
        webData.code = 1001
        webData.mid = UUID.randomUUID().toString()
        val currentTimeSeconds = System.currentTimeMillis() / 1000
        webData.timeunix = currentTimeSeconds
        webData.fid = "1"
        val jsMD5 =
            MD5Utils.getJsMD5(webData.code.toString() + "_" + webData.mid + "_" + webData.timeunix.toString())
        webData.sign = MD5Utils.getJsMD5(jsMD5)
        val socketUserBean = WebSocketUserBean()
        socketUserBean.usertype = 1
        socketUserBean.username = "测试"
        socketUserBean.userid = ManageApplication.getDeviceInfo()
        webData.body = socketUserBean
        WebSocketHelper.getInstance().sendSocketString(GsonUtils.parseClassToJson(webData))
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onUiEvent(uiEvent: UIEvent) {
        when (uiEvent.event) {
            Const.CODE2001.toString() -> {
                Toast.makeText(context, "这就是新消息", Toast.LENGTH_LONG).show()
            }

            Const.CODE2002.toString() -> {
                Toast.makeText(context, "限制使用", Toast.LENGTH_LONG).show()
                spUtils.setParam(Const.DISABLEPAD, true)
                goMainActivity()
            }

            Const.CODE2003.toString() -> {
                Toast.makeText(context, "解除限制", Toast.LENGTH_LONG).show()
                spUtils.setParam(Const.DISABLEPAD, false)
                goMainActivity()
            }

            Const.CODE2004.toString() -> {
               //请求接口更新策略
            }

            Const.CODE2005.toString() -> {
                ManageApplication.rebootDevice()
            }

            Const.CODE2006.toString() -> {
                ManageApplication.launchFactoryReset()
            }

            Const.LOGAPPSTART -> {
                val message = uiEvent.message
                if (lastPkgName == message) {
                    return
                }
                val filter = appList.filter { it.packageName == message }
                if (filter.isNotEmpty()) {
                    lastPkgName = message
                    val data = LogdOperateBean()
                    ManageApplication.getDeviceInfo()?.let {
                        data.sn = it
                    }
                    data.appPackage = message
                    data.doEvent = EventLog.STARTAPPEVENT
                    eventLog(data)
                }
            }

            Const.APPINSTALL -> {
                val message = uiEvent.message
                val data = LogdOperateBean()
                ManageApplication.getDeviceInfo()?.let {
                    data.sn = it
                }
                data.appPackage = message
                data.comm = "应用安装"
                data.doEvent = EventLog.APPINSTALLEVENT
                eventLog(data)
            }

            Const.APPUNINSTALL -> {
                val message = uiEvent.message
                val data = LogdOperateBean()
                ManageApplication.getDeviceInfo()?.let {
                    data.sn = it
                }
                data.appPackage = message
                data.comm = "应用卸载"
                data.doEvent = EventLog.APPUNINSTALLEVENT
                eventLog(data)
            }

            "10086" -> {
                serviceScope.launch {
                    logService.postLogdoperateAdd(LogdOperateBean())
                }
                Toast.makeText(context, "违规操作，安装未知应用", Toast.LENGTH_LONG).show()
                goMainActivity()
            }
        }
    }

    private fun goMainActivity() {
        try {
            // 为应用程序的启动Activity 准备Intent
            val launchIntent = Intent()
            launchIntent.setComponent(
                ComponentName(
                    "com.xhly.manageapp",
                    "com.xhly.manageapp.ui.MainActivity"
                )
            )
            launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            context.startActivity(launchIntent)
        } catch (e: Exception) {
            LogShow("跳转失败$e")
        }
    }

    //用来发送事件日志
    private fun eventLog(operateBean: LogdOperateBean) {
        serviceScope.launch {
            logService.postLogdoperateAdd(operateBean)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)
        serviceScope.cancel()
        /* stopForeground(Service.STOP_FOREGROUND_REMOVE)*/
        val intent = Intent()
        intent.setPackage("com.xhly.manageapp")
        intent.setAction("test")
        context.sendBroadcast(intent)
        LogShow("Service被销毁")
    }


    private fun downLoadFile(url: String) {
        serviceScope.launch {
            withContext(Dispatchers.IO) {
                //val file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                val file = context.getExternalFilesDir(null)
                val name = file.toString()
                val downloader = Downloader.Builder().build()
                val request = Download.Request.Builder()
                    .url("https://dl.hdslb.com/mobile/latest/android64/iBiliPlayer-bili.apk?t=20230728&spm_id_from=333.47.b_646f776e6c6f61642d6c696e6b.1")
                    .into(File(name, "test.apk"))
                    .build()
                LogShow("开始下载")
                val execute = downloader.newCall(request).execute()
                val successful = execute.isSuccessful()
                LogShow("下载结果" + successful)
                if (successful) {
                    withContext(Dispatchers.Main) {
                        ManageApplication.installPackage(File(name, "test.apk").toString())
                    }
                }
                LogShow("下载后，开始安装")
            }
        }
    }

}