package com.dlc.exam.ui.mock

import android.annotation.SuppressLint
import android.content.Context
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.ITopicChange
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.MockAnswerReq
import com.rc.httpcore.vo.response.ExamTopic

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

    companion object {
        const val FRAGMENT_TAG = "MockTestFragment"

        fun newInstance() = MockTestFragment()
    }

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

    private var mITopicChange: ITopicChange? = null

    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is ITopicChange) {
            this.mITopicChange = context
        }
    }

    override fun onDetach() {
        this.mITopicChange = null
        super.onDetach()
    }

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

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

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

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

        mOptionAdapter.setOnItemClickListener { _, _, position ->
            // 当前题目已经提交过答案，不可再次作答
            if (mAnsweredTopic.contains(mCurrentNum)) return@setOnItemClickListener

            val item = mOptionAdapter.getItem(position)
            if (mTopicType == TopicType.MULTI.type) {
                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<MockAnswerReq.Answer>()
                val answer = MockAnswerReq.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()
            }
        }
    }

    /**
     * 上一题
     */
    private fun dispatchPrevTopic() {
        val prevIndex = mCurrentNum - 2
        if (prevIndex < 0) {
            showToast("已经是第一题")
            return
        }
        mITopicChange?.onTopicChanged(prevIndex)
    }

    /**
     * 下一题
     */
    private fun dispatchNextTopic() {
        val nextIndex = mCurrentNum
        if (nextIndex >= mTopicTotal) {
            showToast("已经是最后题")
            return
        }
        mITopicChange?.onTopicChanged(nextIndex)
    }

    /**
     * 多选题的答题卡被点击
     */
    fun onMultiSheetClick(callback: () -> Unit) {
        // 当前题目已经提交过答案，不可再次作答
        if (mAnsweredTopic.contains(mCurrentNum)) {
            callback.invoke()
            return
        }

        val checkedItems = mOptionAdapter.data.filter {   it.checked }
        if (checkedItems.isNullOrEmpty()) {
            // 未作答，直接返回
            callback.invoke()
            return
        }
        // 已作答，提交答案，更新答题结果
        val answerList = checkedItems.map { MockAnswerReq.Answer().apply { id = it.id } }
        callMockAnswerApi(answerList, callback = callback)
    }

    /**
     * 多选提交
     *
     * @param prev ture:上一题 false:下一题
     */
    private fun multiSubmit(prev: Boolean) {
        // 当前题目已经提交过答案，不可再次作答
        if (mAnsweredTopic.contains(mCurrentNum)) {
            dispatchChangeTopic(prev)
            return
        }

        val checkedItems = mOptionAdapter.data.filter {  it.checked }
        if (checkedItems.isNullOrEmpty()) {
            // 未作答，直接进入下一题
            dispatchChangeTopic(prev)
            return
        }
        val answerList = checkedItems.map { MockAnswerReq.Answer().apply { id = it.id } }
        callMockAnswerApi(answerList, prev)
    }

    private fun dispatchChangeTopic(prev: Boolean) {
        if (prev) {
            dispatchPrevTopic()
        } else {
            dispatchNextTopic()
        }
    }

    @SuppressLint("SetTextI18n")
    private fun callMockAnswerApi(
        answerList: List<MockAnswerReq.Answer>,
        prev: Boolean? = null,
        callback: (() -> Unit)? = null
    ) {
        showLoading("保存中...")
        val param = MockAnswerReq()

        param.practiseId = mTopicInfo?.practiseId
        param.quId = mTopicInfo?.quId
        param.answerList = answerList
        val disposable = ApiRepository.mockAnswer(param)
            .subscribe({
                dismissLoading()
                // 答案提交成功
                // 1) 更新选项状态
                mAnsweredTopic.add(mCurrentNum)
                mOptionAdapter.answered = true
                mOptionAdapter.notifyDataSetChanged()
                // 2) 更新答案
                val isRight = isAnswerRight(answerList)
                val answeredInfo = AnsweredInfo(
                    myAnswer = if (isRight) "正确" else "错误",
                    textColor = if (isRight) "#349CFB" else "#FF6060",
                    rightAnswer = topicAnswer()
                )
                viewBinding.myAnswer.text = answeredInfo.myAnswer
                viewBinding.myAnswer.setTextColor(Color.parseColor(answeredInfo.textColor))
//                viewBinding.topicAnswer.text = "答案：${answeredInfo.rightAnswer}"
                mAnsweredInfoMap[mCurrentNum] = answeredInfo
                viewBinding.answerInfo.visibility = View.VISIBLE

                // 3) 更新左侧统计
                mITopicChange?.onAnswered(mCurrentNum - 1, isRight)

                if (null != callback) {
                    callback.invoke()
                    return@subscribe
                }

                // 4) 如果是多选，提交答案后，需要切换题目(多选：通过'上一题/下一题'提交答案并切换题目)
                if (mTopicType == TopicType.MULTI.type) {
                    dispatchChangeTopic(prev!!)
                }
            }, { throwable ->
                dismissLoading()
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }

    private val mAnsweredInfoMap = mutableMapOf<Int, AnsweredInfo>()

    data class AnsweredInfo(val myAnswer: String, val textColor: String, val rightAnswer: String)

    private fun topicAnswer(): String {
        val answer = StringBuilder()
        mTopicInfo?.answerList?.forEach {
            if ( it.isRight) answer.append(it.abc)
        }
        return answer.toString()
    }

    /**
     * 判断用户答案是否正确
     *
     * @param userAnswer 用户答案
     */
    private fun isAnswerRight(userAnswer: List<MockAnswerReq.Answer>): Boolean {
        // 标准答案
        val rightAnswer = mTopicInfo?.answerList?.filter { 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
    }

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

    private val mOptionAdapter by lazy { TopicOptionAdapter() }

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

        // 选项
        mOptionAdapter.answered = mAnsweredTopic.contains(mCurrentNum)
        mOptionAdapter.setNewInstance(data?.answerList)

        // 答案
        if (mOptionAdapter.answered) {
            viewBinding.answerInfo.visibility = View.VISIBLE
            // 显示答案
            mAnsweredInfoMap[mCurrentNum]?.let {
                viewBinding.myAnswer.text = it.myAnswer
                viewBinding.myAnswer.setTextColor(Color.parseColor(it.textColor))
//                viewBinding.topicAnswer.text = "答案：${it.rightAnswer}"
            }
        } else {
            viewBinding.answerInfo.visibility = View.GONE
        }
    }

}

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

    var answered: Boolean = false

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

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

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

}