package com.dlc.eboard.ui.leave

import android.annotation.SuppressLint
import android.os.*
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import com.bumptech.glide.Glide
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.dlc.eboard.R
import com.dlc.eboard.common.CommonUtils
import com.dlc.eboard.databinding.FragmentLeaveFaceMatchingBinding
import com.dlc.eboard.event.OnlineUserEvent
import com.dlc.eboard.iflytek.AudioPlayerManager
import com.dlc.eboard.sp.DeviceSp
import com.dlc.eboard.ui.dialog.ResultEnum
import com.dlc.eboard.ui.dialog.SafetyCheckResultDialog
import com.rc.core.ui.fragment.RcBaseFragment
import com.rc.core.ui.widget.decoration.GridSpacingItemDecoration
import com.rc.core.util.DeviceUtils
import com.rc.core.util.Format
import com.rc.httpcore.client.ApiRepository
import com.rc.httpcore.vo.response.SignInCheckResp
import org.greenrobot.eventbus.EventBus
import java.lang.ref.WeakReference

/**
 * 离开人脸比对
 *
 * @author ReiChin_
 */
open class LeaveFaceMatchingFragment :
    RcBaseFragment<FragmentLeaveFaceMatchingBinding>() {

    protected var mStudentInfo: SignInCheckResp? = null
    private val weakHandler by lazy { WeakReferenceHandler(this) }
    companion object {
        const val TAG = "LeaveFaceMatchingFragment"

        fun newInstance(data: SignInCheckResp?): LeaveFaceMatchingFragment {
            val args = Bundle()
            args.putParcelable("data", data)
            val fragment = LeaveFaceMatchingFragment()
            fragment.arguments = args
            return fragment
        }
    }

    override fun createViewBinding(
        inflater: LayoutInflater,
        container: ViewGroup?
    ): FragmentLeaveFaceMatchingBinding {
        return FragmentLeaveFaceMatchingBinding.inflate(inflater, container, false)
    }

    override fun initViews(savedInstanceState: Bundle?) {
        mStudentInfo = arguments?.getParcelable("data")

        viewBinding.cameraViewRoot.visibility = View.GONE
        refreshPersonViews()
        showLeaveCheckView()
    }

    @SuppressLint("SetTextI18n")
    protected open fun refreshPersonViews() {
        mStudentInfo?.let { data ->
            // 头像
            Glide.with(this)
                .load(data.singInUser.avatar)
                .placeholder(R.mipmap.icon_sign_in_avatar)
                .error(R.mipmap.icon_sign_in_avatar)
                .into(viewBinding.personProfile)
            // 姓名
            viewBinding.personName.text = data.singInUser.nickName
            // 学号
            viewBinding.schoolNumber.text = "学号：${data.singInUser.userName ?: ""}"
            // 准入资格到期时间
            viewBinding.expirationDate.text =
                "准入资格到期时间：${
                    Format.formatZonedDateTime(
                        data.singInUser.expirationDate,
                        "yyyy年MM月dd日"
                    )
                }"
            updateViolationViews(data)
        }
    }

    protected open fun updateViolationViews(data: SignInCheckResp) {
    }

    /**
     * 人脸验证成功后，调用此方法，显示离开检查相关View
     */
    protected fun showLeaveCheckView() {
        val laboratoryVo = DeviceSp.loadLaboratoryVo(requireActivity())
        if (null == laboratoryVo) {
            showToast("暂无实验室信息，即将重新获取")
            CommonUtils.restartApp(requireActivity())
            return
        }

        viewBinding.singInViolationGroup.visibility = View.GONE
        viewBinding.checkContentGroup.visibility = View.VISIBLE

        val adapter = CheckItemAdapter(laboratoryVo.outCheck)
        adapter.setOnItemClickListener { _, _, position ->
            adapter.updateCheckStatus(position)
        }
        viewBinding.checkContentFlow.layoutManager = GridLayoutManager(requireActivity(), 2)
        val decor = GridSpacingItemDecoration(2, DeviceUtils.dip2px(requireActivity(), 30.0f),
            DeviceUtils.dip2px(requireActivity(), 7.0f),false)
        viewBinding.checkContentFlow.addItemDecoration(decor)
        viewBinding.checkContentFlow.adapter = adapter
        viewBinding.confirm.setOnClickListener {
            val selectedSize = adapter.selectedSize()
            if (selectedSize != laboratoryVo.outCheck.size) {
                SafetyCheckResultDialog(
                    requireContext(),
                    ResultEnum.WARNING,
                    "请确认以上工作已完成",
                    3000
                ).show()
            } else {
                callLeaveApi()
            }
        }
    }

    /**
     * 人脸验证成功后，调用此方法
     */
    protected fun callLeaveApi() {
        showLoading("保存中...")
        val disposable = ApiRepository.signOut(mStudentInfo!!.code)
            .subscribe({ success ->
                if (success) {
                    EventBus.getDefault().post(OnlineUserEvent())
                    AudioPlayerManager.speakVoice(R.raw.audio_success_leave)
                    weakHandler.sendEmptyMessageDelayed(1, 1000)
//                    object : Handler(Looper.getMainLooper()) {
//                        override fun handleMessage(msg: Message) {
//                            dismissLoading()
//                            requireActivity().finish()
//                        }
//                    }.sendEmptyMessageDelayed(1, 1000)
                }
            }, { throwable ->
                dismissLoading()
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }


    // static + 弱引用  防止内存泄露
    class WeakReferenceHandler(obj: LeaveFaceMatchingFragment) : Handler(Looper.getMainLooper()) {
        private val mRef: WeakReference<LeaveFaceMatchingFragment> = WeakReference(obj)

        override fun handleMessage(msg: Message) {
            mRef.get()?.run {
                dismissLoading()
                requireActivity().finish()
            }
        }
    }

    override fun onDestroy() {
        weakHandler.removeCallbacksAndMessages(null)
        super.onDestroy()
    }
}

private class CheckItemAdapter(datas: List<String>?) :
    BaseQuickAdapter<String, BaseViewHolder>(R.layout.item_check_item, datas?.toMutableList()) {

    private val mSelectedStatusMap by lazy { mutableMapOf<Int, Boolean>() }

    fun updateCheckStatus(position: Int) {
        val checkStatus = mSelectedStatusMap.getOrElse(position, { false })
        mSelectedStatusMap[position] = !checkStatus
        notifyItemChanged(position)
    }

    fun selectedSize(): Int {
        return mSelectedStatusMap.values.fold(0, { acc, selected ->
            if (selected) acc + 1 else acc
        })
    }

    override fun convert(holder: BaseViewHolder, item: String) {
        val checkStatus = mSelectedStatusMap.getOrElse(holder.adapterPosition, { false })
        holder.setText(R.id.check_content, item)
            .setVisible(R.id.check_selected, checkStatus)
    }

}