package com.dlc.chemical.ui

import android.content.*
import android.hardware.usb.UsbManager
import android.os.*
import android.util.Log
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.widget.Toast
import com.bumptech.glide.Glide
import com.dlc.chemical.BuildConfig
import com.dlc.chemical.ChemicalApp
import com.dlc.chemical.R
import com.dlc.chemical.common.CommonUtils
import com.dlc.chemical.common.Constants
import com.dlc.chemical.databinding.ActivityMainBinding
import com.dlc.chemical.iflytek.AudioPlayerManager
import com.dlc.chemical.mqtt.MqttService
import com.dlc.chemical.mqtt.event.UpdateEvent
import com.dlc.chemical.print.UsbReceiver
import com.dlc.chemical.serial.listener.OnSerialScanListener
import com.dlc.chemical.serial.port.scan.PortScanHelper
import com.dlc.chemical.serial.port.scan.PortScanService
import com.dlc.chemical.sp.ConfLogoSp
import com.dlc.chemical.ui.common.*
import com.dlc.chemical.ui.login.LoginActivity
import com.dlc.chemical.ui.operate.OperateRecordActivity
import com.dlc.chemical.ui.query.QueryChemicalsActivity
import com.dlc.chemical.ui.settings.PasswordDialog
import com.dlc.chemical.ui.settings.SettingsActivity
import com.dlc.chemical.ui.tag.SelectTagTypeActivity
import com.dlc.chemical.ui.tag.TagManagementActivity
import com.dlc.chemical.ui.unlock.SelectAuthMethodActivity
import com.dlc.chemical.ui.waring.WaringRecordActivity
import com.rc.core.util.ApkUpdater
import com.rc.core.util.DeviceUtils
import com.rc.httpcore.HttpClient
import com.rc.httpcore.client.ApiRepository
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.lang.ref.WeakReference
import java.text.SimpleDateFormat
import java.util.*

/**
 * 首页
 *
 * @author ReiChin_
 */
class MainActivity : BaseCountDownActivity<ActivityMainBinding>() {
    private val weakHandler by lazy { WeakReferenceHandler(this) }

    companion object {
        private const val REQ_LOGIN = 100
    }

    override fun createViewBinding() = ActivityMainBinding.inflate(LayoutInflater.from(this))

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        EventBus.getDefault().register(this)
        if (Constants.Mock.MQTT_ENABLED) {
            bindService(Intent(this, MqttService::class.java), mConnection, BIND_AUTO_CREATE)
        }
        startService(Intent(this, PortScanService::class.java))

        registerUsbBroadcast()

        if (Constants.Mock.TEST_ENV) {
            Handler(Looper.getMainLooper()).postDelayed({
                handleScanEvent(Constants.Mock.STUDENT_NUM)
            }, 1500)
        }
    }

    private var mUsbReceiver: UsbReceiver? = null

    private fun registerUsbBroadcast() {
        if (null == mUsbReceiver) {
            val filter = IntentFilter().apply {
                addAction(UsbReceiver.ACTION_USB_PERMISSION)
                addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
                addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
                addAction(UsbReceiver.ACTION_USB_STATE) // usb连接状态广播
            }
            mUsbReceiver = UsbReceiver()
            registerReceiver(mUsbReceiver, filter)
        }
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        registerUsbBroadcast()
    }

    override fun onDestroy() {
        EventBus.getDefault().unregister(this)
        if (Constants.Mock.MQTT_ENABLED) {
            unbindService(mConnection)
        }
//        weakHandler.removeCallbacks(mMenuHandler)
        weakHandler.removeCallbacksAndMessages(null)
        stopService(Intent(this, PortScanService::class.java))
        super.onDestroy()
    }

    private val mConnection: ServiceConnection = object : ServiceConnection {

        override fun onServiceConnected(name: ComponentName, service: IBinder) {
            service as MqttService.MqttBinder
            service.initMqtt()
        }

        override fun onServiceDisconnected(name: ComponentName) {
        }
    }

    override fun onRestart() {
        super.onRestart()
        if (null != ChemicalApp.sLearnLoginVo) {
            val disposable = ApiRepository.authValidation()
                .subscribe({
                    ChemicalApp.sLearnLoginVo?.isManager = it
                    refreshLoginStatusViews()
                }, { throwable ->
                    showNetError(throwable)
                    throwable.printStackTrace()
                })
            addDisposable(disposable)
        }
    }

    override fun onResume() {
        refreshLoginStatusViews()

        mPortScanHelper.onResume()
        registerUsbBroadcast()
        super.onResume()
    }

    private fun refreshLoginStatusViews() {
        if (null == ChemicalApp.sLearnLoginVo) {
            viewBinding.notLoginLayout.visibility = View.VISIBLE
            viewBinding.loginLayout.visibility = View.GONE
            viewBinding.unlock.visibility = View.GONE
        } else {
            viewBinding.notLoginLayout.visibility = View.GONE
            viewBinding.loginLayout.visibility = View.VISIBLE

            viewBinding.loginUser.text = ChemicalApp.sLearnLoginVo!!.nickName
            viewBinding.loginRole.text = ChemicalApp.sLearnLoginVo!!.positionName

            // 实验室管理+配置了锁柜
            val showUnlock =
                ChemicalApp.sLearnLoginVo!!.isManager && ChemicalApp.sLearnLoginVo!!.cabinetLock
            viewBinding.unlock.visibility = if (showUnlock) View.VISIBLE else View.GONE
        }
    }

    override fun initViews(savedInstanceState: Bundle?) {
        weakHandler.sendEmptyMessage(1)
//        object : Handler(Looper.getMainLooper()) {
//            override fun handleMessage(msg: Message) {
//                val format = SimpleDateFormat("yyyy年MM月dd日 EEEE HH:mm", Locale.getDefault())
//                val calendar = Calendar.getInstance(Locale.getDefault())
//                viewBinding.nowTime.text =
//                    format.format(Calendar.getInstance(Locale.getDefault()).time)
//
//                // 10:04:15.250  next minute: 44s:750
//                val second = calendar.get(Calendar.SECOND) // 15
//                val millisecond = calendar.get(Calendar.MILLISECOND) // 250
//                val delayMillis = (59 - second) * 1000 + (1000 - millisecond)
//                sendEmptyMessageDelayed(1, delayMillis.toLong())
//            }
//        }.sendEmptyMessage(1)


    }

    override fun initListener() {
        viewBinding.titleBar.setOnLongClickListener {
            PasswordDialog(this) {
                val intent = Intent(this, SettingsActivity::class.java)
                startActivity(intent)
            }.show()
            true
        }

        // 退出登录
        viewBinding.logout.setOnClickListener {
            showLoading("退出中...")
            val disposable = ApiRepository.loginOut()
                .subscribe({
                    dismissLoading()
                    showToast("已退出登录")
                    ChemicalApp.sLearnLoginVo = null
                    HttpClient.token = null
                    stopCountDown()
                    refreshLoginStatusViews()
                }, { throwable ->
                    dismissLoading()
                    showNetError(throwable)
                })
            addDisposable(disposable)
        }

        // 开锁
        viewBinding.unlock.setOnClickListener {
            val intent = Intent(this, SelectAuthMethodActivity::class.java)
            intent.putExtra("lockType", LockType.SYSTEM.code)
            startActivity(intent)
        }

        // 领用化学品
        viewBinding.use.setOnClickListener {
            dispatchMenuClicked {
                if (Constants.Mock.USE_FLOW_NEWLY) {
                    val intent = Intent(this, QueryChemicalsActivity::class.java)
                    intent.putExtra("moduleEnum", ModuleEnum.USE)
                    startActivity(intent)
                } else {
                    if (true == ChemicalApp.sLearnLoginVo?.cabinetLock) {
                        // 有智能锁
                        val intent = Intent(this, QueryChemicalsActivity::class.java)
                        intent.putExtra("moduleEnum", ModuleEnum.USE)
                        startActivity(intent)
                    } else {
                        val intent = Intent(this, TagScanActivity::class.java)
                        intent.putExtra("moduleEnum", ModuleEnum.USE)
                        startActivity(intent)
                    }
                }
            }
        }
        // 归还化学品
        viewBinding.revert.setOnClickListener {
            dispatchMenuClicked {
                val intent = Intent(this, TagScanActivity::class.java)
                intent.putExtra("moduleEnum", ModuleEnum.REVERT)
                startActivity(intent)
            }
        }
        // 使用记录
        viewBinding.operateRecord.setOnClickListener {
            dispatchMenuClicked {
                startActivity(Intent(this, OperateRecordActivity::class.java))
            }
        }
        // 报警台账
        viewBinding.waringRecord.setOnClickListener {
            dispatchMenuClicked {
                startActivity(Intent(this, WaringRecordActivity::class.java))
            }
        }
        // 化学品入库
        viewBinding.inputStore.setOnClickListener {
            dispatchMenuClicked {
                val intent = Intent(this, QueryChemicalsActivity::class.java)
                intent.putExtra("moduleEnum", ModuleEnum.INPUT_STORE)
                startActivity(intent)
            }
        }
        // 化学品出库
        viewBinding.outputStore.setOnClickListener {
            dispatchMenuClicked {
                if (true == ChemicalApp.sLearnLoginVo?.cabinetLock) {
                    // 有智能锁
                    val intent = Intent(this, QueryChemicalsActivity::class.java)
                    intent.putExtra("moduleEnum", ModuleEnum.OUTPUT_STORE)
                    startActivity(intent)
                } else {
                    val intent = Intent(this, TagScanActivity::class.java)
                    intent.putExtra("moduleEnum", ModuleEnum.OUTPUT_STORE)
                    startActivity(intent)
                }
            }
        }
        // 标签管理
        viewBinding.tagManagement.setOnClickListener {
            dispatchMenuClicked {
                if (true == ChemicalApp.sLearnLoginVo?.airBottle) {
                    // 配置了气瓶标签
                    val intent = Intent(this, SelectTagTypeActivity::class.java)
                    startActivity(intent)
                } else {
                    val intent = Intent(this, TagManagementActivity::class.java)
                    startActivity(intent)
                }
            }
        }
        // 查询化学品
        viewBinding.queryChemicals.setOnClickListener {
            if (isLogin(false)) {
                val intent = Intent(this, QueryChemicalsActivity::class.java)
                intent.putExtra("moduleEnum", ModuleEnum.QUERY)
                startActivity(intent)
            } else {
                val intent = Intent(this, TagScanActivity::class.java)
                intent.putExtra("moduleEnum", ModuleEnum.QUERY)
                startActivity(intent)
            }
        }
    }

    private var mMenuHandler: (() -> Unit)? = null

    private fun dispatchMenuClicked(callback: () -> Unit) {
//        mMenuHandler = callback
        Log.d("aaaaaaaaaaaa", "11111111111111111111")
        if (isLogin()) callback.invoke()
    }

    private fun isLogin(speak: Boolean = true): Boolean {
        if (null != ChemicalApp.sLearnLoginVo) {
            return true
        }
        Log.d("=======================", "2222222222222")
        if (speak) AudioPlayerManager.speakVoice(R.raw.audio_please_login)
        return false
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (REQ_LOGIN == requestCode) {
            if (RESULT_OK == resultCode) {
                // 登录成功
                startCountDown()
                refreshLoginStatusViews()
                AudioPlayerManager.speakVoice(R.raw.audio_welcome)

                mMenuHandler?.invoke()
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onUpdateEventEvent(event: UpdateEvent) {
        if (CommonUtils.stringParseInt(event.data.version) > DeviceUtils.getVersionCode(this)) {
            // 显示版本更新
            downloadApk(event.data.apkUploadFile)
        }
    }

    private var apkDownloading = false

    private fun downloadApk(downloadUrl: String) {
        if (apkDownloading) return
        apkDownloading = true
        callApkUpdateApi("2")
        ApkUpdater(this, BuildConfig.APPLICATION_ID, callback = object :
            ApkUpdater.DownloadCallback {
            override fun onProgress(progress: Int) {
            }

            override fun onFailed(errMsg: String?) {
                apkDownloading = false
                callApkUpdateApi("0")
            }

            override fun onSuccess(apkFile: String) {
                apkDownloading = false
                callApkUpdateApi("1")
            }

        }).downloadApk(downloadUrl)
    }

    /*
     * state 0:升级失败; 1:升级成功; 2:升级中
     */
    private fun callApkUpdateApi(state: String) {
        val disposable = ApiRepository.onepcApkUpdate(CommonUtils.getAndroidId(), state)
            .subscribe({ }, { })
        addDisposable(disposable)
    }

    private var mHandleScanEvent = false

    private val mPortScanHelper by lazy {
        PortScanHelper(this, object : OnSerialScanListener {
            override fun dispatchScanEvent(type: OnSerialScanListener.ScanType, content: String) {
                if (!mHandleScanEvent) {
                    handleScanEvent(content)
                }
            }

        })
    }

    private fun handleScanEvent(content: String) {
        if (isLogin(false)) return

        // 登录
        mHandleScanEvent = true
        showLoading("查询中...")
        val disposable =
            ApiRepository.learnLogin(content, CommonUtils.getAndroidId())
                .subscribe({
                    dismissLoading()
                    ChemicalApp.sLearnLoginVo = it

                    if (Constants.Mock.JUMP_LOGON_FACE) {
                        // 跳过登录人脸检测
                        callLearnLoginApi(content) {
                            // 登录成功
                            startCountDown()
                            refreshLoginStatusViews()
                            AudioPlayerManager.speakVoice(R.raw.audio_welcome)
                        }
                    } else {
                        // 切换到人脸比对画面
                        val intent = Intent(this, LoginActivity::class.java)
                        intent.putExtra("username", content)
                        startActivityForResult(intent, REQ_LOGIN)
                        mHandleScanEvent = false
                    }
                }, { throwable ->
                    dismissLoading()
                    throwable.printStackTrace()
                    showNetError(throwable)
                    mHandleScanEvent = false
                })
        addDisposable(disposable)
    }

    private fun callLearnLoginApi(username: String, callback: () -> Unit) {
        showLoading("查询中...")
        val disposable =
            ApiRepository.learnLogin(username, CommonUtils.getAndroidId(), true)
                .subscribe({ data ->
                    dismissLoading()
                    ChemicalApp.sLearnLoginVo = data
                    callback.invoke()
                    mHandleScanEvent = false
                }, { throwable ->
                    dismissLoading()
                    throwable.printStackTrace()
                    showNetError(throwable)
                    mHandleScanEvent = false
                })
        addDisposable(disposable)
    }

    override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
        mPortScanHelper.dispatchKeyEvent(event)
        return super.dispatchKeyEvent(event)
    }

    override fun onPause() {
        mPortScanHelper.onPause()
        super.onPause()
    }

    // static + 弱引用  防止内存泄露
    class WeakReferenceHandler(obj: MainActivity) : Handler(Looper.getMainLooper()) {
        private val mRef: WeakReference<MainActivity> = WeakReference(obj)
        override fun handleMessage(msg: Message) {
            mRef.get()?.run {
                val format = SimpleDateFormat("yyyy年MM月dd日 EEEE HH:mm", Locale.getDefault())
                val calendar = Calendar.getInstance(Locale.getDefault())
                viewBinding.nowTime.text =
                    format.format(Calendar.getInstance(Locale.getDefault()).time)

                // 10:04:15.250  next minute: 44s:750
                val second = calendar.get(Calendar.SECOND) // 15
                val millisecond = calendar.get(Calendar.MILLISECOND) // 250
                val delayMillis = (59 - second) * 1000 + (1000 - millisecond)
                weakHandler.sendEmptyMessageDelayed(1, delayMillis.toLong())
                ConfLogoSp.loadConfLogo(this)?.let { conf ->
                    Glide.with(this)
                        .load(conf.rectangleLogo)
                        .into(viewBinding.sysLogo)
                }
            }
        }
    }
}
