package com.dlc.exam.ui.learn.test

import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.dlc.exam.R
import com.dlc.exam.common.TopicType
import com.dlc.exam.databinding.FragmentExamTopicBinding
import com.dlc.exam.ui.score.ExamAnswer
import com.dlc.exam.ui.score.PaperQuViewModel
import com.rc.core.ui.fragment.RcBaseFragment
import com.rc.httpcore.client.ApiRepository
import com.rc.httpcore.vo.request.ExamAnswerReq
import com.rc.httpcore.vo.response.ExamTopic

/**
 * info
 *
 * @author ReiChin_
 */
class ClassTestFragment : RcBaseFragment<FragmentExamTopicBinding>() {

    companion object {
        const val FRAGMENT_TAG = "ClassTestFragment"

        fun newInstance() = ClassTestFragment()
    }

    private val viewModel by lazy {
        ViewModelProvider(requireActivity(), ViewModelProvider.NewInstanceFactory()).get(
            PaperQuViewModel::class.java
        )
    }

    // 题目信息
    private var mTopicInfo: ExamTopic.ElPaperQu? = null

    // 已经提交过答案的题目编号
    private val mAnsweredTopic = mutableSetOf<Int>()

    private var mCurrentNum: Int = 1 // 当前题目编号
    private var mTopicTotal: Int = 0 // 总题目数据
    private var mTopicType: String? = null // 当前题目类型：单选/多选/判断

    private val mOptionAdapter by lazy { TopicOptionAdapter() }

    override fun createViewBinding(
        inflater: LayoutInflater,
        container: ViewGroup?
    ) = FragmentExamTopicBinding.inflate(inflater, container, false)

    @SuppressLint("SetTextI18n")
    override fun initViews(savedInstanceState: Bundle?) {
        viewBinding.remainingTimeLabel.visibility = View.GONE
        viewBinding.remainingTime.visibility = View.GONE
        viewBinding.topicTypeDesc.visibility = View.GONE
        viewBinding.answerInfo.visibility = View.GONE

        viewModel.paperQuData.observe(viewLifecycleOwner) { data ->
            mTopicInfo = data
            mCurrentNum = data.currentNum
            mTopicTotal = data.topicTotal
            updateViews(data)
        }

        viewModel.groupInfoData.observe(viewLifecycleOwner) { data ->
            mCurrentNum = data.currentNum
            mTopicType = data.topicType.type
            viewBinding.topicType.text = data.topicType.desc
        }

        viewModel.retestData.observe(viewLifecycleOwner) {
            // 从新开始课后考核
            mAnsweredTopic.clear()
            mCurrentNum = 1
            mTopicTotal = 0
            mTopicType = null
            viewBinding.topic.text = null
            mOptionAdapter.setNewInstance(null)
        }

        mOptionAdapter.setOnItemClickListener { _, _, position ->
            val item = mOptionAdapter.getItem(position)
            if (mTopicType == TopicType.MULTI.type) {
//                item.checked = if ("1" == item.checked) "0" else "1"
                item.checked = true != item.checked
                mOptionAdapter.notifyItemChanged(position)
            } else {
                // 单选/判断
                // 1) 更新选项状态
//                mOptionAdapter.data.forEach { it.checked = "0" }
                mOptionAdapter.data.forEach { it.checked = false }
                item.checked = true
                mOptionAdapter.notifyDataSetChanged()

                // 2) 选项点击后直接提交答案
                val answerList = mutableListOf<ExamAnswerReq.Answer>()
                val answer = ExamAnswerReq.Answer().apply { id = item.id }
                answerList.add(answer)
                callMockAnswerApi(answerList)
            }
        }
        viewBinding.topicOptions.layoutManager = LinearLayoutManager(requireContext())
        viewBinding.topicOptions.adapter = mOptionAdapter

        viewBinding.prevTopic.setOnClickListener {
            //  上一题
            if (mTopicType == TopicType.MULTI.type) {
                // 多选题
                multiSubmit(true)
            } else {
                dispatchPrevTopic()
            }
        }
        viewBinding.nextTopic.setOnClickListener {
            // 下一题
            if (mTopicType == TopicType.MULTI.type) {
                // 多选题
                multiSubmit(false)
            } else {
                dispatchNextTopic()
            }
        }
    }

    /**
     * 上一题
     *
     * @param answered ture:当前题目已做答，需要更新答题卡
     */
    private fun dispatchPrevTopic(answered: Boolean = false, isRight: Boolean = false) {
        val prevIndex = mCurrentNum - 2
        if (prevIndex < 0) {
            showToast("已经是第一题")
            return
        }
        val examAnswer = ExamAnswer(mCurrentNum - 1, prevIndex, mAnsweredTopic.size, answered, isRight)
        viewModel.setExamAnswer(examAnswer)
    }

    /**
     * 下一题
     *
     * @param answered ture:当前题目已做答，需要更新答题卡
     */
    private fun dispatchNextTopic(answered: Boolean = false, isRight: Boolean = false) {
        val nextIndex = mCurrentNum
        if (nextIndex >= mTopicTotal) {
            showToast("已经是最后题")
            return
        }
        val examAnswer = ExamAnswer(mCurrentNum - 1, nextIndex, mAnsweredTopic.size, answered, isRight)
        viewModel.setExamAnswer(examAnswer)
    }

    /**
     * 多选题的答题卡被点击
     */
    fun onMultiSheetClick(callback: (sheetInx: Int, answeredCnt: Int, right: Boolean) -> Unit) {
//        val checkedItems = mOptionAdapter.data.filter { "1" == it.checked }
        val checkedItems = mOptionAdapter.data.filter { it.checked }
        if (checkedItems.isNullOrEmpty()) {
            // 未作答，直接返回
            callback.invoke(-1, mAnsweredTopic.size, false)
            return
        }
        // 已作答，提交答案，更新答题结果
        val answerList = checkedItems.map { ExamAnswerReq.Answer().apply { id = it.id } }
        callMockAnswerApi(answerList, callback = callback)
    }

    /**
     * 多选提交
     *
     * @param prev ture:上一题 false:下一题
     */
    private fun multiSubmit(prev: Boolean) {
//        val checkedItems = mOptionAdapter.data.filter { "1" == it.checked }
        val checkedItems = mOptionAdapter.data.filter { it.checked }
        if (checkedItems.isNullOrEmpty()) {
            // 未作答，直接进入下一题
            dispatchChangeTopic(prev)
            return
        }
        val answerList = checkedItems.map { ExamAnswerReq.Answer().apply { id = it.id } }
        callMockAnswerApi(answerList, prev)
    }

    private fun dispatchChangeTopic(prev: Boolean, answered: Boolean = false, isRight: Boolean = false) {
        if (prev) {
            dispatchPrevTopic(answered, isRight)
        } else {
            dispatchNextTopic(answered, isRight)
        }
    }

    /**
     * 提交题目答案
     */
    private fun callMockAnswerApi(
        elPaperQuAnswerList: List<ExamAnswerReq.Answer>,
        prev: Boolean? = null,
        callback: ((sheetInx: Int, answeredCnt: Int, right: Boolean) -> Unit)? = null
    ) {
        showLoading("保存中...")
        val param = ExamAnswerReq()

        param.paperId = mTopicInfo?.paperId
        param.quId = mTopicInfo?.quId
        param.elPaperQuAnswerList = elPaperQuAnswerList
        val disposable = ApiRepository.examFillAnswer(param)
            .subscribe({
                dismissLoading()
                // 答案提交成功
                mAnsweredTopic.add(mCurrentNum)
                val isRight = isAnswerRight(elPaperQuAnswerList)
                if (null != callback) {
                    callback.invoke(mCurrentNum - 1, mAnsweredTopic.size, isRight)
                    return@subscribe
                }

                if (mTopicType == TopicType.MULTI.type) {
                    dispatchChangeTopic(prev!!, true, isRight)
                } else {
                    // 答案提交成功，自动切换到下一题
                    val examAnswer = ExamAnswer(mCurrentNum - 1, mCurrentNum, mAnsweredTopic.size, true, isRight)
                    viewModel.setExamAnswer(examAnswer)
                }
            }, { throwable ->
                dismissLoading()
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }

    /**
     * 判断用户答案是否正确
     *
     * @param userAnswer 用户答案
     */
    private fun isAnswerRight(userAnswer: List<ExamAnswerReq.Answer>): Boolean {
        // 标准答案
//        val rightAnswer = mTopicInfo?.elPaperQuAnswerList?.filter { "1" == it.isRight }
        val rightAnswer = mTopicInfo?.elPaperQuAnswerList?.filter { true == it.isRight }
        if (userAnswer.size != rightAnswer?.size) return false

        // rightAnswer: ["111", "222", "333"]
        // userAnswer: ["222", "333", "444"]
        val rightIds = rightAnswer.map { it.id }
        val userIds = userAnswer.map { it.id }

        // 用户答案中，不包含标准答案
        val error = rightIds.find { !userIds.contains(it) }
        return null == error
    }

    @SuppressLint("SetTextI18n")
    private fun updateViews(data: ExamTopic.ElPaperQu?) {
        // 题干
        // 18、题目名称题目名称题目名称题目名称题目名称题目名称题目名称题目名称。
        viewBinding.topic.text = "${data?.currentNum ?: ""}、${data?.content ?: ""}"

        // 选项
        mOptionAdapter.setNewInstance(data?.elPaperQuAnswerList)
    }

}

private class TopicOptionAdapter :
    BaseQuickAdapter<ExamTopic.ElPaperQuAnswer, BaseViewHolder>(R.layout.item_topic_option) {

    override fun convert(holder: BaseViewHolder, item: ExamTopic.ElPaperQuAnswer) {
        holder.setText(R.id.optionText, "${item.abc}: ${item.content}")
            .setTextColor(R.id.optionText, optionTextColor(item.checked))
            .setImageResource(R.id.optionRadio, radioImageResource(item.checked))
    }

    private fun optionTextColor(checked: Boolean): Int {
        return when (checked) {
            true -> Color.parseColor("#349CFB")
            else -> Color.parseColor("#333333")
        }
    }

    private fun radioImageResource(checked: Boolean): Int {
        return when (checked) {
            true -> R.drawable.ic_radio_on_right
            else -> R.drawable.ic_radio_off
        }
    }

}