package com.yzx.escreen

import android.annotation.SuppressLint
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.widget.ContentLoadingProgressBar
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.allenliu.versionchecklib.v2.AllenVersionChecker
import com.allenliu.versionchecklib.v2.builder.UIData
import com.allenliu.versionchecklib.v2.callback.CustomDownloadingDialogListener
import com.blankj.utilcode.constant.PermissionConstants
import com.blankj.utilcode.util.*
import com.flyco.tablayout.listener.CustomTabEntity
import com.flyco.tablayout.listener.OnTabSelectListener
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.lzy.okgo.OkGo
import com.lzy.okgo.callback.StringCallback
import com.lzy.okgo.model.Response
import com.qmuiteam.qmui.widget.dialog.QMUIDialog
import com.yzx.escreen.activity.LoginActivity
import com.yzx.escreen.activity.base.BaseActivity
import com.yzx.escreen.config.Config
import com.yzx.escreen.config.RefreshToken
import com.yzx.escreen.fragment.HomeFragment
import com.yzx.escreen.fragment.SettingFragment
import com.yzx.escreen.fragment.VisitorFragment
import com.yzx.escreen.model.*
import com.yzx.escreen.presenter.MainPresenter
import com.yzx.escreen.presenter.MainView
import com.yzx.escreen.utils.hideNavigationBar
import com.yzx.escreen.widget.*
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.dialog_leave.view.sureBtn
import kotlinx.android.synthetic.main.dialog_sure.view.closeBtn
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.java_websocket.client.WebSocketClient
import org.java_websocket.drafts.Draft_6455
import org.java_websocket.handshake.ServerHandshake
import org.jetbrains.anko.find
import org.jetbrains.anko.toast
import java.net.URI
import java.util.*


/**
 * Yun.Lei
 * 2020年5月6日14:49:10
 */
class MainActivity : BaseActivity<MainPresenter>(), NetworkUtils.OnNetworkStatusChangedListener,
    MainView {


    override val inflateId: Int
        get() = R.layout.activity_main
    var netLoadingDialog: QMUIDialog? = null
    var netErrorDialog: QMUIDialog? = null
    private val netLoadingRun = Runnable {
        netLoadingDialog?.apply {
            dismiss()
        }
        showNetworkError()
    }
    private var idsLoading = false
    private var isAutoShowLeave = false
    private var isAutoShowChange = false

    private val mHandler = Handler(Looper.getMainLooper())
    private val runnable = object : Runnable {
        override fun run() {
            val isAutoShowLeave = SPUtils.getInstance().getBoolean("auto_show_leave", true)
            val isAutoShowChange = SPUtils.getInstance().getBoolean("auto_show_change", true)
            if (isAutoShowLeave || isAutoShowChange) {
                if (!idsLoading && NetworkUtils.isConnected()) {
                    idsLoading = true
                    LogUtils.d("获取详情开始--ids", TimeUtils.getNowMills())
                    mPresenter?.getLeaveShowIds()
                }
                mHandler.postDelayed(this, 2000)
            } else {
                mHandler.removeCallbacks(this)
            }

        }
    }

    private val mTimeHandler = Handler(Looper.getMainLooper())
    private val timeRunnable = object : Runnable {
        override fun run() {
            EventBus.getDefault().post(TimeShow().getNowObj())
            mTimeHandler.postDelayed(this, 1000)
        }
    }

    private val dialogList = mutableListOf<ConstraintLayout>()

    private var client: WebSocketClient? = null

    private val mHeartHandler = Handler()
    private val mHeartRunnable = object : Runnable {
        override fun run() {
            mHeartHandler.removeCallbacks(this)
            // 在这里编写定时任务的逻辑
            Log.d("Timer", "定时任务执行")
            if (NetworkUtils.isConnected()) {
                wsHeart()
            }
            // 定时任务完成后，再次调度定时任务
            mHeartHandler.postDelayed(this, 10 * 1000) // 10000毫秒后再次执行
        }
    }

    private val mWsHandler = Handler()
    private val mWsRunnable = object : Runnable {
        override fun run() {
            mWsHandler.removeCallbacks(this)
            // 在这里编写定时任务的逻辑
            Log.d("Timer", "定时任务执行")
            if (NetworkUtils.isConnected()) {
                initWs()
            }
        }
    }

    override fun initView() {
        if (NetworkUtils.isConnected()) {
            if (!User.isLogin() && User.getUser().token.isEmpty()) {
//                WebActivity.active(this, "${Config.OA_URL}/login")
                LoginActivity.active(this)
                finish()
            }
            if (!User.isLogin()) {
                RefreshToken.refresh(object : RefreshToken.RefreshCallback {
                    override fun onSuccess() {
                        checkVersion()
                        checkAuto()
                    }

                    override fun onError() {

                    }
                })
            } else {
                checkVersion()
                checkAuto()
                RefreshToken.refresh(object : RefreshToken.RefreshCallback {
                    override fun onSuccess() {
                    }

                    override fun onError() {

                    }
                })
            }
        } else {
            showNetworkLoading()        //显示网络检查中
        }
        val tabData = arrayListOf<CustomTabEntity>()
        tabData.add(TabEntity("学生请假", R.mipmap.leave_select, R.mipmap.leave_unselect))
//        tabData.add(TabEntity("学籍异动", R.mipmap.change_select, R.mipmap.change_unselect))
        tabData.add(TabEntity("访客管理", R.mipmap.visitor_select, R.mipmap.visitor_unselect))
//        tabData.add(TabEntity("我的", R.mipmap.my_select, R.mipmap.my_unselect))
        tabData.add(TabEntity("设置", R.mipmap.setting_select, R.mipmap.setting))
        tabLayout.setTabData(tabData)

        viewPager2.adapter = HomePagerAdapter(this)
        viewPager2.offscreenPageLimit = 3
        viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
            override fun onPageSelected(position: Int) {
                super.onPageSelected(position)
                tabLayout.currentTab = position
            }
        })
        tabLayout.setOnTabSelectListener(object : OnTabSelectListener {
            override fun onTabSelect(position: Int) {
//                viewPager2.currentItem = position
                viewPager2.setCurrentItem(position, false)
                KeyboardUtils.hideSoftInput(viewPager2)
            }

            override fun onTabReselect(position: Int) {
            }

        })

        mTimeHandler.post(timeRunnable)
    }

    private fun checkAuto() {
        isAutoShowLeave = SPUtils.getInstance().getBoolean("auto_show_leave", true)
        isAutoShowChange = SPUtils.getInstance().getBoolean("auto_show_change", true)
        if (isAutoShowLeave || isAutoShowChange) {
            mHandler.removeCallbacks(runnable)
            mHandler.postDelayed(runnable, 2000)
        } else {
            mHandler.removeCallbacks(runnable)
        }
    }

    //接收消息
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(event: AutoSwitchChange) {
        checkAuto()
    }

    //接收消息
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(event: UserLoginEvent) {
        if (client?.isOpen == true) {
            client?.close()
        }
        client = null
    }

    override fun onDestroy() {
        super.onDestroy()
        mTimeHandler.removeCallbacks(timeRunnable)
        mHeartHandler.removeCallbacks(mHeartRunnable)
        mWsHandler.removeCallbacks(mWsRunnable)
        if (client?.isOpen == true) {
            client?.close()
        }
    }

    //接收请假消息
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(detail: StuLeave) {
        removeOld(detail.id, 0)
        val dialog = LeaveDialog(this)
        dialog.layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        dialog.setData(detail)
        dialog.setTag(R.id.tag_dialog_name, detail.id)
        dialog.setTag(R.id.tag_dialog_type, 0)
        dialog.onCloseClick = {
            dialogLayout.removeView(it)
            dialogList.remove(it)
        }
        dialog.onSureClick = { view, item ->

            val sureDialog = Dialog(this,R.style.TransparentDialog)
            val tempView = LayoutInflater.from(this).inflate(R.layout.dialog_sure, null, false)
            sureDialog.setContentView(tempView)
            tempView.sureBtn.setOnClickListener {
                sureDialog.dismiss()
                dialogLayout.removeView(view)
                dialogList.remove(view)
                EventBus.getDefault().post(SureOutSchool(item))
            }
            tempView.closeBtn.setOnClickListener {
                sureDialog.dismiss()
            }
            sureDialog.hideNavigationBar()
            sureDialog.show()

//            val sureDialog = QMUIDialog.MessageDialogBuilder(this)
//            sureDialog.setMessage("是否确认已放行？")
//            sureDialog.setTitle("温馨提示")
//            sureDialog.addAction("取消"){ _dialog, index ->
//                _dialog?.dismiss()
//            }
//            sureDialog.addAction("确认"){ _dialog, index ->
//                _dialog?.dismiss()
//                dialogLayout.removeView(view)
//                dialogList.remove(view)
//                EventBus.getDefault().post(SureOutSchool(item))
//            }
//            sureDialog.show()
            showSureDialog()
        }
        dialogLayout.addView(dialog)
        dialogList.add(dialog)
    }

    fun showSureDialog() {

    }

    //接收异动消息
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(detail: StuChange) {
        removeOld(detail.id, 1)
        val dialog = ChangeDialog(this)
        dialog.layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        dialog.setData(detail)
        dialog.setTag(R.id.tag_dialog_name, detail.id)
        dialog.setTag(R.id.tag_dialog_type, 1)
        dialog.onCloseClick = {
            dialogLayout.removeView(it)
            dialogList.remove(it)
        }
        dialogLayout.addView(dialog, 0)  //请假权限更高，异动插入到最底层
        dialogList.add(dialog)
    }

    //接收访客消息
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(detail: Visitor) {
        removeOld(detail.id, 2)
        val dialog = VisitorDialog(this)
        dialog.layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        dialog.setData(detail)
        dialog.setTag(R.id.tag_dialog_name, detail.id)
        dialog.setTag(R.id.tag_dialog_type, 2)
        dialog.onCloseClick = {
            dialogLayout.removeView(it)
            dialogList.remove(it)
        }
        dialogLayout.addView(dialog, 0)  //请假权限更高，访客插入到最底层
        dialogList.add(dialog)
    }

    //接收查看图片消息
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(detail: ViewImage) {
        removeOld(detail.id, 3)
        val dialog = ViewImageDialog(this)
        dialog.layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        dialog.setData(detail)
        dialog.setTag(R.id.tag_dialog_name, detail.id)
        dialog.setTag(R.id.tag_dialog_type, 3)
        dialog.onCloseClick = {
            dialogLayout.removeView(it)
            dialogList.remove(it)
        }
        dialogLayout.addView(dialog)
        dialogList.add(dialog)
    }

    private fun removeOld(id: Int, type: Int) {
        val view = dialogList.find {
            val tagId: Int = it.getTag(R.id.tag_dialog_name) as Int
            val tagType: Int = it.getTag(R.id.tag_dialog_type) as Int
            return@find id == tagId && type == tagType
        }
        view?.apply {
            dialogList.remove(this)
            dialogLayout.removeView(this)
        }
    }

    override fun initData() {
        NetworkUtils.registerNetworkStatusChangedListener(this)
        PermissionUtils.permissionGroup(PermissionConstants.STORAGE)
            .rationale { activity, shouldRequest ->

            }.callback(object : PermissionUtils.FullCallback {
                override fun onGranted(granted: MutableList<String>) {
                    LogUtils.d("权限通过", granted)
                }

                override fun onDenied(
                    deniedForever: MutableList<String>,
                    denied: MutableList<String>
                ) {
                    LogUtils.d("权限拒绝", denied)
                }

            }).theme { activity -> ScreenUtils.setFullScreen(activity) }
            .request()

    }

    override fun onResume() {
        super.onResume()
        if (NetworkUtils.isConnected() && User.isLogin() && User.getUser().user_id > 0 && client?.isOpen !== true) {
            initWs()
        }
    }

    private fun initWs() {
        if (!NetworkUtils.isConnected()) {
            LogUtils.d("initWs-无网络")
            return
        }
        LogUtils.d("initWs-有网络")
        client =
            object : WebSocketClient(URI.create(Config.WS_URL), Draft_6455(), null, 10 * 1000) {
                override fun onOpen(handshakedata: ServerHandshake?) {
                    LogUtils.d("initWs-WebSocketClient-onOpen", handshakedata)
                    val user = User.getUser()
                    val clientInfo = YzxClientInfo()
                    clientInfo.type = 70
                    clientInfo.user_id = user.user_id.toString()
                    clientInfo.unit_id = user.school_id.toString()
                    clientInfo.token = user.token

                    client?.send(Gson().toJson(clientInfo))

                }

                override fun onClose(code: Int, reason: String?, remote: Boolean) {
                    LogUtils.d("initWs-WebSocketClient-onClose", code, reason, remote)
                    mWsHandler.postDelayed(mWsRunnable, 60 * 1000)
                }

                override fun onMessage(message: String?) {
                    LogUtils.d("initWs-WebSocketClient-onMessage", message)
                    if (message?.startsWith("ECHO:", true) == false) {
                        wsMessage(message)
                    }
                }

                override fun onError(ex: Exception?) {
                    LogUtils.d("initWs-WebSocketClient-onError", ex)
                    mWsHandler.postDelayed(mWsRunnable, 60 * 1000)
                }

            }
        try {
            client?.connectBlocking()
//                wsHeart()
            mHeartHandler.postDelayed(mHeartRunnable, 10 * 1000)
        } catch (e: InterruptedException) {
            e.printStackTrace()
            LogUtils.d("initWs-WebSocketClient-catch", e)
        }
    }

    private fun wsMessage(msg: String) {
        val resultType = object : TypeToken<YzxClientInfo>() {}.type
        val gson = Gson()
        val res = gson.fromJson<YzxClientInfo>(msg, resultType)
        if (res.data.student_id > 0) {
            if (isAutoShowLeave || isAutoShowChange) {
                LogUtils.d("WebSocketClient--wsMessage", res)
                EventBus.getDefault().post(EventLeaveIds("${res.data.student_id}"))
//                mPresenter?.getLeaveShowIds("${res.data.student_id}")
            }
        }
    }

    //请假消息
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(detail: EventLeaveIds) {
        LogUtils.d("WebSocketClient--onMessageEvent", detail)
        mPresenter?.getLeaveShowIds("${detail.ids}")
    }

    //请假消息
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(detail: UserVersionCheck) {
        LogUtils.d("WebSocketClient--onMessageEvent", detail)
        checkVersion(true)
    }


    private fun wsHeart() {
        if (NetworkUtils.isConnected()) {
            LogUtils.d("initWs-wsHeart-有网络")
            if (client?.isOpen == true) {
                client?.apply {
                    send(Gson().toJson(YzxHeart().getYzxHeader()))
                }
            } else {
                try {
                    if (client != null) {
                        client?.reconnectBlocking()
                    } else {
                        initWs()
                    }
                } catch (e: Exception) {
                    LogUtils.d("initWs-wsHeart-有网络，异常", e)
                }
            }
//            wsHeart()
        } else {
            LogUtils.d("initWs-wsHeart-无网络")
        }
    }

    private fun showNetworkError() {
        if (!NetworkUtils.isConnected()) {        //无网提示
            val builder = QMUIDialog.MessageDialogBuilder(this)

            builder.setMessage("你还没有连接网络，请先连接网络！")
                .setTitle("温馨提示")
                .addAction(
                    "去设置"
                ) { dialog, index ->
                    NetworkUtils.openWirelessSettings()
                }
                .setCancelable(false)
                .setCanceledOnTouchOutside(false)
            netErrorDialog = builder.show()
            netErrorDialog?.hideNavigationBar()
        }
    }

    private fun showNetworkLoading() {
        val builder = QMUIDialog.MessageDialogBuilder(this)

        builder.setMessage("网络检查中,请稍后...")
            .setTitle("温馨提示")
            .setCancelable(false)
            .setCanceledOnTouchOutside(false)
        netLoadingDialog = builder.show()
        netLoadingDialog?.hideNavigationBar()

        viewPager2.postDelayed(netLoadingRun, 5000)
    }

    override fun initPresenter(): MainPresenter = MainPresenter(this)

    @SuppressLint("SetTextI18n")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
    }

    override fun onBackPressed() {
//        super.onBackPressed()
    }

    override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME) {
            return true
        }
        return super.onKeyUp(keyCode, event)
    }

    override fun onDisconnected() {
        showNetworkError()
    }

    override fun onConnected(networkType: NetworkUtils.NetworkType?) {
        netLoadingDialog?.apply {
            if (isShowing) {
                dismiss()
            }
        }
        netErrorDialog?.apply {
            if (isShowing) {
                dismiss()
            }
        }
        viewPager2.removeCallbacks(netLoadingRun)
        if (!User.isLogin()) {
//            WebActivity.active(this, "${Config.OA_URL}/login?logout=1")
            LoginActivity.active(this)
            finish()
        }
        checkVersion()
        checkAuto()
        initWs()
    }

    private fun checkVersion(userCheck: Boolean = false): Unit {
        val BASE_URL = Config.BASE_URL
        OkGo.post<String>("$BASE_URL/parent/common/getInkBottleMaxVersion")
            .tag(this)
            .params("app_id", Config.APP_ID)
            .execute(object : StringCallback() {

                override fun onSuccess(response: Response<String>) {
                    val json = response.body()
                    Log.d("checkVersion", "onSuccess: ${json}")
                    val resultType = object : TypeToken<BaseBean<Version>>() {}.type
                    val gson = Gson()
                    val res = gson.fromJson<BaseBean<Version>>(json, resultType)
                    if (res.code == 0) {
                        val appVersion = AppUtils.getAppVersionName()
                        val appVersionCode = AppUtils.getAppVersionCode()
                        val versionCode = res?.data?.version_code ?: 0
                        val curr = Date().time
                        val lastTipTime = SPUtils.getInstance()
                            .getLong("last_tip_time${res.data.version_code}", 0)
                        if (versionCode > appVersionCode) {     //有新版本
                            when {
                                res.data.type == 1 -> {   //强制升级
                                    updateApp(res.data)
                                }

                                curr - lastTipTime > 24 * 60 * 60 * 1000 -> {     //非强制一天以内提示一次
                                    updateApp(res.data)
                                }

                                userCheck -> {      //
                                    updateApp(res.data)
                                }
                            }

                        } else {
                            if (userCheck) {
                                toast("已经是最新版本了！")
                            }
                        }
                    }
                }

            })


    }


    private fun updateApp(version: Version) {
        AllenVersionChecker
            .getInstance()
            .downloadOnly(
                UIData.create()
                    .setTitle("检测到新版本")
                    .setContent(version.explain)
                    .setDownloadUrl(version.app_src)
            )
            .setCustomVersionDialogListener { context, versionBundle ->
                val dialog = BaseDialog(context, R.style.BaseDialog, R.layout.version_dialog)
                val title = dialog.find<TextView>(R.id.tv_title)
                title.text = "检测到新版本"
                val content = dialog.find<TextView>(R.id.tv_msg)
                content.text = version.explain
                val cancelBtn = dialog.find<View>(R.id.cancel_btn)
                if (version.type == 1) {
                    cancelBtn.visibility = View.GONE
                }
                dialog.hideNavigationBar()
                return@setCustomVersionDialogListener dialog
            }
            .setOnCancelListener {
                SPUtils.getInstance().put("last_tip_time${version.version_code}", Date().time)
            }
            .setCustomDownloadingDialogListener(object : CustomDownloadingDialogListener {
                @SuppressLint("SetTextI18n")
                override fun updateUI(dialog: Dialog?, progress: Int, versionBundle: UIData?) {
                    val tvProgress: TextView = dialog!!.findViewById(R.id.tv_progress)
                    val progressBar: ContentLoadingProgressBar = dialog.findViewById(R.id.pb)
                    progressBar.progress = progress
                    tvProgress.text = "$progress%"

                    Log.d("checkVersion", "onSuccess: ${progress}")
                }

                override fun getCustomDownloadingDialog(
                    context: Context?,
                    progress: Int,
                    versionBundle: UIData?
                ): Dialog {
                    val downDialog = BaseDialog(
                        context!!,
                        R.style.BaseDialog,
                        R.layout.download_dialog
                    )
                    downDialog.hideNavigationBar()
                    return downDialog
                }

            })
            .executeMission(this)
    }

    override fun onLeaveIDsSuccess(list: MutableList<LeaveID>) {
        idsLoading = false
        LogUtils.d("WebSocketClient--获取详情结束--ids", list)
        val listLeave = list.filter { it.type == 0 }.toMutableList()
        val listChange = list.filter { it.type == 1 }.toMutableList()
        var type = 0
        if (listLeave.isNotEmpty() && isAutoShowLeave) {
            viewPager2.currentItem = 0
            type = 0
        } else if (listChange.isNotEmpty() && isAutoShowChange) {
            viewPager2.currentItem = 1
            type = 1
        }
        if (list.isNotEmpty() && (isAutoShowLeave || isAutoShowChange)) {
            viewPager2.postDelayed({
                EventBus.getDefault().post(MessageEventAuto(list, type))
            }, 500)
        }
    }

    override fun onLeaveIDsError() {
        LogUtils.d("获取详情结束--ids", TimeUtils.getNowMills())
        idsLoading = false
    }

    override fun onStart() {
        super.onStart()
        EventBus.getDefault().register(this)
    }

    override fun onStop() {
        mHandler.removeCallbacks(runnable)
        super.onStop()
        EventBus.getDefault().unregister(this)
    }


}

class HomePagerAdapter(act: AppCompatActivity) : FragmentStateAdapter(act) {
    override fun getItemCount(): Int = 4

    override fun createFragment(position: Int): Fragment {
        when (position) {
            0 -> {
                return HomeFragment.getNewInstance()
            }

//            1 -> {
//                return ChangeFragment.getNewInstance()
//            }

            1 -> {
                return VisitorFragment.getNewInstance()
            }

            2 -> {
                return SettingFragment.getNewInstance()
            }
        }
        return HomeFragment()
    }

}