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 core.ui.fragment.RcBaseFragment
import core.ui.widget.decoration.GridSpacingItemDecoration
import core.util.Format
import core.util.OnWeakListener
import core.util.WeakHandler
import http.client.ApiRepository
import http.vo.response.SignInCheckResp
import org.greenrobot.eventbus.EventBus
import xn.xxp.R
import xn.xxp.app.LabApp
import xn.xxp.databinding.FragmentLeaveFaceMatchingBinding
import xn.xxp.home.auth.ResultEnum
import xn.xxp.home.auth.SafetyCheckResultDialog
import xn.xxp.mqtt.event.OnlineUserEvent
import xn.xxp.utils.AudioPlayer
import xn.xxp.utils.Tool
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

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

    protected var mStudentInfo: SignInCheckResp? = null
    private val weakHandler by lazy { WeakHandler(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 ?: ""}"

            val isoDateTime = data.singInUser.expirationDate

            // 1. 解析ISO格式的日期时间
            val dateTime = LocalDateTime.parse(isoDateTime, DateTimeFormatter.ISO_DATE_TIME)
            // 2. 格式化为中文日期
            val chineseFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日")
            val formattedDate = dateTime.format(chineseFormatter)
            // 准入资格到期时间
            viewBinding.expirationDate.text =
                "准入资格到期时间：${
                    formattedDate
                }"
            updateViolationViews(data)
        }
    }

    protected open fun updateViolationViews(data: SignInCheckResp) {
    }

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

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

        val adapter = CheckItemAdapter(laboratoryVo.outCheck)
        adapter.setOnItemClickListener { _, _, position ->
            adapter.updateCheckStatus(position)
        }
        ///requireActivity()
//        viewBinding.checkContentFlow.layoutManager = GridLayoutManager(requireContext(), 2)
        viewBinding.checkContentFlow.layoutManager = GridLayoutManager(requireActivity(), 2)

        val decor = GridSpacingItemDecoration(
            2, Tool.INSTANCE.dip2px(30f), Tool.INSTANCE.dip2px(7f), false
        )
        viewBinding.checkContentFlow.addItemDecoration(decor)
        viewBinding.checkContentFlow.adapter = adapter
        viewBinding.confirm.setOnClickListener {
            val selectedSize = adapter.selectedSize()
            if (selectedSize != laboratoryVo.outCheck.size) {
                SafetyCheckResultDialog(
                    requireActivity(),
                    ResultEnum.WARNING,
                    "请确认以上工作已完成",
                    3000
                ).show()
            } else {
                callLeaveApi()
            }
        }
    }

    /**
     * 人脸验证成功后，调用此方法
     */
    protected fun callLeaveApi() {
        showLoading("保存中...")
        val disposable = ApiRepository.signOut(mStudentInfo!!.code)
            .subscribe({ success ->
                if (success) {
                    EventBus.getDefault().post(OnlineUserEvent())
                    AudioPlayer.getInstance().play(R.raw.audio_success_leave)
                    weakHandler.sendEmptyMessageDelayed(1, 1000)
                }
            }, { throwable ->
                dismissLoading()
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }

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

    override fun onWeakHandleMessage(msg: Message) {
        dismissLoading()
        requireActivity().finish()
    }

}

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)
    }

}