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

import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.dlc.exam.ExamApp
import com.dlc.exam.R
import com.dlc.exam.common.TopicType
import com.dlc.exam.databinding.ActivityClassTestBinding
import com.dlc.exam.ui.common.BaseCountDownActivity
import com.dlc.exam.ui.me.PersonalCenterActivity
import com.dlc.exam.ui.score.PaperQuViewModel
import com.dlc.exam.ui.score.TopicGroupInfo
import com.dlc.exam.ui.widget.TitleBar
import com.rc.httpcore.HttpClient
import com.rc.httpcore.client.ApiRepository
import com.rc.httpcore.vo.request.PaperQuReq
import com.rc.httpcore.vo.response.ExamTopic

/**
 * 课后考核
 *
 * @author ReiChin_
 */
class ClassTestActivity : BaseCountDownActivity<ActivityClassTestBinding>(),
    TitleBar.TitleListener {

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

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

    private var mPaperId: String? = null

    private var isAnsweredEnd = false // 是否已经交卷

    // 已经提交过答案的题目 key:题目编号（从1开始） value:是否正确
    private val mAnsweredTopic = mutableMapOf<Int, Boolean>()

    private var mTestPassed = false // 是否测试通过

    override fun initListener() {
        viewBinding.titleBar.setTitleListener(this)

        viewBinding.radioTopicArrow.setOnClickListener {
            dispatchTopicArrowClicked(it as ImageView, viewBinding.radioTopicNumber)
        }
        viewBinding.multiTopicArrow.setOnClickListener {
            dispatchTopicArrowClicked(it as ImageView, viewBinding.multiTopicNumber)
        }
        viewBinding.judgeTopicArrow.setOnClickListener {
            dispatchTopicArrowClicked(it as ImageView, viewBinding.judgeTopicNumber)
        }
        // 完成考核
        viewBinding.submitPaper.setOnClickListener {
            // 判断当前题目是否为多选题，如果是多选题，需要先提交多选题答案，再完成考核
            val groupInfo = viewModel.groupInfoData.value
            if (groupInfo?.topicType?.type == TopicType.MULTI.type) {
                // 多选题：
                val fragment =
                    supportFragmentManager.findFragmentByTag(ClassTestFragment.FRAGMENT_TAG)
                            as? ClassTestFragment
                // 1) 提交答案
                fragment?.onMultiSheetClick { sheetInx, answeredCnt, right ->
                    if (-1 != sheetInx) {
                        mAnsweredTopic[sheetInx + 1] = right

                        // 2) 更新答题卡
                        updateAnswerSheet(sheetInx, answeredCnt)
                    }
                    // 3) 完成考核
                    callMockTestEndApi()
                }
            } else {
                callMockTestEndApi()
            }
        }
    }

    /**
     * 调用完成考核的API
     */
    private fun callMockTestEndApi() {
        showLoading("保存中..")
        val disposable = ApiRepository.handAssess(mPaperId ?: "")
            .subscribe({
                dismissLoading()
                isAnsweredEnd = true
                mTestPassed = "100" == it.accuracy
                // 切换到结束画面
                it.passed = mTestPassed
                it.paperId = mPaperId
                viewModel.setHandPractise(it)

                // 交卷按钮不可见
                viewBinding.submitPaper.visibility = View.GONE
                // 显示正确/错误题目数
                val rightCount = rightCount()
                viewBinding.rightCount.visibility = View.VISIBLE
                viewBinding.rightCount.text = "$rightCount"
                viewBinding.errorCount.visibility = View.VISIBLE
                viewBinding.errorCount.text = "${mAnsweredTopic.size - rightCount}"
                // 答题卡图例调整
                viewBinding.error.visibility = View.VISIBLE
                viewBinding.current.visibility = View.GONE
                // 更新答题卡
                mRadioTopicAdapter.isAnsweredEnd = true
                mRadioTopicAdapter.selectItemId = null
                mRadioTopicAdapter.answeredTopic = mAnsweredTopic
                mRadioTopicAdapter.notifyDataSetChanged()
                mMultiTopicAdapter.isAnsweredEnd = true
                mMultiTopicAdapter.selectItemId = null
                mMultiTopicAdapter.answeredTopic = mAnsweredTopic
                mMultiTopicAdapter.notifyDataSetChanged()
                mJudgeTopicAdapter.isAnsweredEnd = true
                mJudgeTopicAdapter.selectItemId = null
                mJudgeTopicAdapter.answeredTopic = mAnsweredTopic
                mJudgeTopicAdapter.notifyDataSetChanged()

                var fragment =
                    supportFragmentManager.findFragmentByTag(ClassTestCompletedFragment.FRAGMENT_TAG)
                if (null == fragment) fragment = ClassTestCompletedFragment.newInstance()
                val transaction = supportFragmentManager.beginTransaction()
                transaction.replace(
                    R.id.topicContainer,
                    fragment,
                    ClassTestCompletedFragment.FRAGMENT_TAG
                )
                transaction.commit()
            }, { throwable ->
                dismissLoading()
                isAnsweredEnd = false
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }

    private fun rightCount(): Int {
        return mAnsweredTopic.values.filter { it }.size
    }

    private fun dispatchTopicArrowClicked(target: ImageView, recyclerView: RecyclerView) {
        // 是否为展开状态
        val isSpread = target.tag as? Boolean ?: true
        if (isSpread) {
            // 展开状态，点击后变为折叠状态
            recyclerView.visibility = View.GONE
            target.setImageResource(R.mipmap.icon_ksxt_zk)
        } else {
            // 折叠状态，点击后变为展开状态
            recyclerView.visibility = View.VISIBLE
            target.setImageResource(R.mipmap.icon_ksxt_sq)
        }
        target.tag = !isSpread
    }

    private val mRadioTopicAdapter by lazy { TopicNumberAdapter() }
    private val mMultiTopicAdapter by lazy { TopicNumberAdapter() }
    private val mJudgeTopicAdapter by lazy { TopicNumberAdapter() }

    override fun initViews(savedInstanceState: Bundle?) {
        viewBinding.titleBar.setUsername(ExamApp.sLearnLoginVo?.userName)

        initRecycleView(mRadioTopicAdapter, viewBinding.radioTopicNumber)
        initRecycleView(mMultiTopicAdapter, viewBinding.multiTopicNumber)
        initRecycleView(mJudgeTopicAdapter, viewBinding.judgeTopicNumber)

        val transaction = supportFragmentManager.beginTransaction()
        transaction.add(
            R.id.topicContainer,
            ClassTestFragment.newInstance(),
            ClassTestFragment.FRAGMENT_TAG
        )
        transaction.commit()

        viewModel.examExamAnswerData.observe(this) { data ->
            // 用户提交答案后回调
            if (data.answered) {
                mAnsweredTopic[data.sheetInx + 1] = data.right

                updateAnswerSheet(data.sheetInx, data.answeredCnt)
            }
            dispatchNextTopic(data.nextIdx)
        }
        viewModel.retestData.observe(this) {
            // 从新开始课后考核
            var fragment = supportFragmentManager.findFragmentByTag(ClassTestFragment.FRAGMENT_TAG)
            if (null == fragment) fragment = ClassTestFragment.newInstance()
            supportFragmentManager.beginTransaction()
                .replace(R.id.topicContainer, fragment, ClassTestFragment.FRAGMENT_TAG)
                .commit()
            // 重置答题卡
            resetAnswerSheet()
            // 重新生成考卷
            queryMockTestTopic()
        }
    }

    /**
     * 重置答题卡
     */
    private fun resetAnswerSheet() {
        isAnsweredEnd = false
        mAnsweredTopic.clear()

        // 交卷按钮可见
        viewBinding.submitPaper.visibility = View.VISIBLE
        // 不显示正确/错误题目数
        viewBinding.rightCount.visibility = View.GONE
        viewBinding.errorCount.visibility = View.GONE
        // 答题卡图例调整
        viewBinding.error.visibility = View.GONE
        // 重置答题进度
        viewBinding.currentTopic.text = null

        mRadioTopicAdapter.selectItemId = null
        mRadioTopicAdapter.isAnsweredEnd = false
        mRadioTopicAdapter.answeredTopic.clear()
        mRadioTopicAdapter.setNewInstance(null)

        mMultiTopicAdapter.selectItemId = null
        mMultiTopicAdapter.isAnsweredEnd = false
        mMultiTopicAdapter.answeredTopic.clear()
        mMultiTopicAdapter.setNewInstance(null)

        mJudgeTopicAdapter.selectItemId = null
        mJudgeTopicAdapter.isAnsweredEnd = false
        mJudgeTopicAdapter.answeredTopic.clear()
        mJudgeTopicAdapter.setNewInstance(null)
    }

    private fun initRecycleView(numberAdapter: TopicNumberAdapter, recyclerView: RecyclerView) {
        numberAdapter.setOnItemClickListener { adapter, _, position ->
            // 完成考核后，不可切换题目
            if (isAnsweredEnd) return@setOnItemClickListener

            // 答题卡点击了， 判断点击前的题目是否为多选题
            val groupInfo = viewModel.groupInfoData.value
            if (groupInfo?.topicType?.type == TopicType.MULTI.type) {
                // 多选题：
                val fragment =
                    supportFragmentManager.findFragmentByTag(ClassTestFragment.FRAGMENT_TAG)
                            as? ClassTestFragment
                // 1) 提交答案
                fragment?.onMultiSheetClick { sheetInx, answeredCnt, right ->
                    if (-1 != sheetInx) {
                        mAnsweredTopic[sheetInx + 1] = right

                        // 2) 更新答题卡
                        updateAnswerSheet(sheetInx, answeredCnt)
                    }
                    // 3) 处理答题卡点击-切换题目
                    dispatchSheetClicked(position, adapter as TopicNumberAdapter)
                }
            } else {
                // 单选/判断题：处理答题卡点击-切换题目
                dispatchSheetClicked(position, adapter as TopicNumberAdapter)
            }
        }
        recyclerView.layoutManager = GridLayoutManager(this, 5)
        recyclerView.adapter = numberAdapter
    }

    private fun dispatchSheetClicked(position: Int, adapter: TopicNumberAdapter) {
        val item = adapter.getItem(position)
        mRadioTopicAdapter.selectItemId = item.id
        mRadioTopicAdapter.notifyDataSetChanged()
        mMultiTopicAdapter.selectItemId = item.id
        mMultiTopicAdapter.notifyDataSetChanged()
        mJudgeTopicAdapter.selectItemId = item.id
        mJudgeTopicAdapter.notifyDataSetChanged()

        val topicIdx = adapter.indexOffsite + position + 1
        val radioSize = mRadioTopicAdapter.data.size
        val multiSize = mMultiTopicAdapter.data.size
        val judgeSize = mJudgeTopicAdapter.data.size
        val topicTotal = radioSize + multiSize + judgeSize
        queryPaperQuDetail(topicIdx, topicTotal, item.paperId, item.quId)

        if (adapter == mRadioTopicAdapter) {
            viewModel.setTopicGroupInfo(TopicGroupInfo(TopicType.RADIO, currentNum = topicIdx))
        } else if (adapter == mMultiTopicAdapter) {
            viewModel.setTopicGroupInfo(TopicGroupInfo(TopicType.MULTI, currentNum = topicIdx))
        } else if (adapter == mJudgeTopicAdapter) {
            viewModel.setTopicGroupInfo(TopicGroupInfo(TopicType.JUDGE, currentNum = topicIdx))
        }
    }

    /**
     * 提交答案后，自动跳转到下一题
     */
    private fun dispatchNextTopic(nextIdx: Int) {
        // 题目总数
        val radioSize = mRadioTopicAdapter.data.size
        val multiSize = mMultiTopicAdapter.data.size
        val judgeSize = mJudgeTopicAdapter.data.size
        val topicTotal = radioSize + multiSize + judgeSize
        if (nextIdx < 0 || nextIdx >= topicTotal) return

        if (nextIdx < radioSize) {
            // 单选题
            val item = mRadioTopicAdapter.data[nextIdx]
            changeTopic(item, nextIdx, topicTotal)
            viewModel.setTopicGroupInfo(TopicGroupInfo(TopicType.RADIO, currentNum = nextIdx + 1))
        } else if (nextIdx < radioSize + multiSize) {
            // 多选题
            val item = mMultiTopicAdapter.data[nextIdx - radioSize]
            changeTopic(item, nextIdx, topicTotal)
            viewModel.setTopicGroupInfo(TopicGroupInfo(TopicType.MULTI, currentNum = nextIdx + 1))
        } else if (nextIdx < topicTotal) {
            // 判断题
            val item = mJudgeTopicAdapter.data[nextIdx - radioSize - multiSize]
            changeTopic(item, nextIdx, topicTotal)
            viewModel.setTopicGroupInfo(TopicGroupInfo(TopicType.JUDGE, currentNum = nextIdx + 1))
        }
    }

    /**
     * 更新答题卡
     *
     * @param index 当前题目编号，从0开始
     * @param answeredCnt 已答题目数
     */
    private fun updateAnswerSheet(index: Int, answeredCnt: Int) {
        // 题目总数
        val radioSize = mRadioTopicAdapter.data.size
        val multiSize = mMultiTopicAdapter.data.size
        val judgeSize = mJudgeTopicAdapter.data.size
        val topicTotal = radioSize + multiSize + judgeSize
        updateAnsweredProgress(answeredCnt, topicTotal)

        if (index < 0 || index >= topicTotal) return

        if (index < radioSize) {
            // 单选题
            val item = mRadioTopicAdapter.data[index]
            // 当前题目已答
//            item.answered = "1"
            item.answered = true
            mRadioTopicAdapter.notifyDataSetChanged()
        } else if (index < radioSize + multiSize) {
            // 多选题
            val item = mMultiTopicAdapter.data[index - radioSize]
            // 当前题目已答
//            item.answered = "1"
            item.answered = true
            mMultiTopicAdapter.notifyDataSetChanged()
        } else if (index < topicTotal) {
            // 判断题
            val item = mJudgeTopicAdapter.data[index - radioSize - multiSize]
            // 当前题目已答
//            item.answered = "1"
            item.answered = true
            mJudgeTopicAdapter.notifyDataSetChanged()
        }
    }

    private fun changeTopic(item: ExamTopic.ElPaperQu, index: Int, topicTotal: Int) {
        mRadioTopicAdapter.selectItemId = item.id
        mRadioTopicAdapter.notifyDataSetChanged()
        mMultiTopicAdapter.selectItemId = item.id
        mMultiTopicAdapter.notifyDataSetChanged()
        mJudgeTopicAdapter.selectItemId = item.id
        mJudgeTopicAdapter.notifyDataSetChanged()
        queryPaperQuDetail(index + 1, topicTotal, item.paperId, item.quId)
    }

    private fun queryPaperQuDetail(
        currentNum: Int,
        topicTotal: Int,
        paperId: String?,
        quId: String?
    ) {
        showLoading("查询中...")
        val param = PaperQuReq()
        param.paperId = paperId
        param.quId = quId
        val disposable = ApiRepository.paperExamQuDetail(param)
            .subscribe({
                dismissLoading()
                it.currentNum = currentNum
                it.topicTotal = topicTotal
                viewModel.setPaperQu(it)
            }, { throwable ->
                dismissLoading()
                val data = ExamTopic.ElPaperQu()
                data.currentNum = currentNum
                data.topicTotal = topicTotal
                viewModel.setPaperQu(data)
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }

    @SuppressLint("SetTextI18n")
    private fun updateAnsweredProgress(answered: Int, topicTotal: Int) {
        viewBinding.currentTopic.text = "${answered}/${topicTotal}"
    }

    override fun initData() {
        super.initData()
        queryMockTestTopic()
    }

    private fun queryMockTestTopic() {
        val chapterId = intent.getStringExtra("chapterId")
        if (chapterId.isNullOrEmpty()) {
            finish()
            return
        }

        showLoading("加载中...")
        val disposable = ApiRepository.classTestStart(chapterId)
            .subscribe({
                mPaperId = it.id
                dismissLoading()
                updateViews(it)
            }, { throwable ->
                mPaperId = null
                dismissLoading()
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }

    @SuppressLint("SetTextI18n")
    private fun updateViews(data: ExamTopic?) {
        data?.let {
            val topicTotal = it.radioList.size + it.multiList.size + it.judgeList.size
            updateAnsweredProgress(0, topicTotal)

            var firstSelectItem: ExamTopic.ElPaperQu? = null
            if (it.radioList.isNullOrEmpty()) {
                viewBinding.radioTopicGroup.visibility = View.GONE
                viewBinding.radioTopicNumber.visibility = View.GONE
            } else {
                viewBinding.radioTopicGroup.visibility = View.VISIBLE
                viewBinding.radioTopicNumber.visibility = View.VISIBLE
                firstSelectItem = it.radioList[0]
                mRadioTopicAdapter.selectItemId = firstSelectItem.id
                mRadioTopicAdapter.setNewInstance(it.radioList)
                viewModel.setTopicGroupInfo(TopicGroupInfo(TopicType.RADIO))
            }

            if (it.multiList.isNullOrEmpty()) {
                viewBinding.multiTopicGroup.visibility = View.GONE
                viewBinding.multiTopicNumber.visibility = View.GONE
            } else {
                viewBinding.multiTopicGroup.visibility = View.VISIBLE
                viewBinding.multiTopicNumber.visibility = View.VISIBLE
                if (null == firstSelectItem) {
                    firstSelectItem = it.multiList[0]
                    viewModel.setTopicGroupInfo(TopicGroupInfo(TopicType.MULTI))
                }
                mMultiTopicAdapter.selectItemId = firstSelectItem!!.id
                mMultiTopicAdapter.indexOffsite = it.radioList.size
                mMultiTopicAdapter.setNewInstance(it.multiList)
            }

            if (it.judgeList.isNullOrEmpty()) {
                viewBinding.judgeTopicGroup.visibility = View.GONE
                viewBinding.judgeTopicNumber.visibility = View.GONE
            } else {
                viewBinding.judgeTopicGroup.visibility = View.VISIBLE
                viewBinding.judgeTopicNumber.visibility = View.VISIBLE
                if (null == firstSelectItem) {
                    firstSelectItem = it.judgeList[0]
                    viewModel.setTopicGroupInfo(TopicGroupInfo(TopicType.JUDGE))
                }
                mJudgeTopicAdapter.selectItemId = firstSelectItem!!.id
                mJudgeTopicAdapter.indexOffsite = it.radioList.size + it.multiList.size
                mJudgeTopicAdapter.setNewInstance(it.judgeList)
            }

            firstSelectItem?.let { firstItem ->
                queryPaperQuDetail(1, topicTotal, firstItem.paperId, firstItem.quId)
            }
        }
    }

    override fun onHomeViewClicked(view: View) {
        finish()
    }

    override fun onLogoutViewClicked(view: View) {
        callLogoutApi {
            showToast("已退出登录")

            ExamApp.sLearnLoginVo = null
            HttpClient.token = null

            finish()
        }
    }

    override fun onBackViewClicked(view: View) {
        onBackPressed()
        finish()
    }

    override fun onUserViewClicked(view: View) {
        startActivity(Intent(this, PersonalCenterActivity::class.java))
    }

    override fun onBackPressed() {
        if (mTestPassed) {
            setResult(RESULT_OK)
        }
        super.onBackPressed()
    }

}

private class TopicNumberAdapter :
    BaseQuickAdapter<ExamTopic.ElPaperQu, BaseViewHolder>(R.layout.item_topic_number) {

    var indexOffsite = 0

    var selectItemId: String? = null

    var isAnsweredEnd = false // 是否已经交卷

    // 已经提交过答案的题目 key:题目编号（从1开始） value:是否正确
    var answeredTopic = mutableMapOf<Int, Boolean>()

    @SuppressLint("SetTextI18n")
    override fun convert(holder: BaseViewHolder, item: ExamTopic.ElPaperQu) {
        val topicNumber = indexOffsite + holder.adapterPosition + 1
        val itemView = holder.itemView as TextView
        itemView.text = "$topicNumber"
        itemView.setBackgroundResource(itemBgResource(item.answered, item.id, topicNumber))
    }

    private fun itemBgResource(answered: Boolean, id: String, topicNumber: Int): Int {
        return when {
            id == selectItemId ->
                R.drawable.circle_radius_10_blue
            answered ->
                if (isAnsweredEnd) {
                    if (answeredTopic[topicNumber] == true)
                        R.drawable.circle_radius_10_blue_20p
                    else
                        R.drawable.circle_radius_10_ffdada
                } else
                    R.drawable.circle_radius_10_blue_20p
            else ->
                R.drawable.circle_radius_10_a2
        }
    }


}