package com.dlc.exam.ui.mock

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.ActivityMockTestBinding
import com.dlc.exam.ui.common.BaseCountDownActivity
import com.dlc.exam.ui.me.PersonalCenterActivity
import com.dlc.exam.ui.score.ITopicChange
import com.dlc.exam.ui.score.PaperQuViewModel
import com.dlc.exam.ui.score.TopicGroupInfo
import com.dlc.exam.ui.widget.TitleBar
import com.rc.core.log.RcLog
import com.rc.httpcore.HttpClient
import com.rc.httpcore.client.ApiRepository
import com.rc.httpcore.vo.request.HandPractiseReq
import com.rc.httpcore.vo.request.PaperQuReq
import com.rc.httpcore.vo.response.ExamTopic

/**
 * 模拟练习
 *
 * @author ReiChin_
 */
class MockTestActivity : BaseCountDownActivity<ActivityMockTestBinding>(),
    ITopicChange, TitleBar.TitleListener {

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

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

    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
            RcLog.info("===多选题${groupInfo?.topicType?.type}       ${TopicType.MULTI.type} ")
            if (groupInfo?.topicType?.type == TopicType.MULTI.type) {
                // 多选题：
                val fragment =
                    supportFragmentManager.findFragmentByTag(MockTestFragment.FRAGMENT_TAG)
                            as? MockTestFragment
                // 1) 提交答案
                fragment?.onMultiSheetClick {
                    // 2) 结束练习
                    callMockTestEndApi()
                }
            } else {
                callMockTestEndApi()
            }
        }
    }

    private var isAnsweredEnd = false

    private fun callMockTestEndApi() {
        showLoading("保存中..")
        val param = HandPractiseReq().apply {
            id = mPractiseId
        }
        val disposable = ApiRepository.handPractise(param)
            .subscribe({
                dismissLoading()
                isAnsweredEnd = true
                // 切换到结束画面
                viewModel.setHandPractise(it)

                viewBinding.submitPaper.visibility = View.GONE

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

    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,
            MockTestFragment.newInstance(),
            MockTestFragment.FRAGMENT_TAG
        )
        transaction.commit()
    }

    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(MockTestFragment.FRAGMENT_TAG)
                            as? MockTestFragment
                // 1) 提交答案
                fragment?.onMultiSheetClick {
                    // 2) 处理答题卡点击-切换题目
                    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 topicTotal =
            mRadioTopicAdapter.data.size + mMultiTopicAdapter.data.size + mJudgeTopicAdapter.data.size
        queryPaperQuDetail(topicIdx, topicTotal, item.practiseId, 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))
        }
    }

    /**
     * 用户点击了上一题/下一题时回调
     *
     * @param index 要切换到的题目编号，从0开始
     */
    override fun onTopicChanged(index: Int) {
        // 完成练习后，不可切换题目
        if (isAnsweredEnd) return

        // 题目总数
        val radioSize = mRadioTopicAdapter.data.size
        val multiSize = mMultiTopicAdapter.data.size
        val judgeSize = mJudgeTopicAdapter.data.size
        val topicTotal = radioSize + multiSize + judgeSize
        if (index < 0 || index >= topicTotal) return

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

    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.practiseId, item.quId)
    }

    private fun queryPaperQuDetail(
        currentNum: Int,
        topicTotal: Int,
        practiseId: String?,
        quId: String?
    ) {
        showLoading("查询中...")
        val param = PaperQuReq()
        param.practiseId = practiseId
        param.quId = quId
        val disposable = ApiRepository.paperMockQuDetail(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)
    }

    private var mRightCnt = 0
    private var mErrorCnt = 0

    /**
     * 用户答案提交成功后回调
     *
     * @param index 当前题目编号，从0开始
     * @param right 是否回答正确
     */
    override fun onAnswered(index: Int, right: Boolean) {
        if (right) {
            mRightCnt++
        } else {
            mErrorCnt++
        }

        // 题目总数
        val radioSize = mRadioTopicAdapter.data.size
        val multiSize = mMultiTopicAdapter.data.size
        val judgeSize = mJudgeTopicAdapter.data.size
        val topicTotal = radioSize + multiSize + judgeSize
        // 1) ①更新正确/错误答题数；②更新总答题数
        updateAnsweredProgress(topicTotal)

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

        // 2) 更新题号显示色
        if (index < radioSize) {
            // 单选题
            val item = mRadioTopicAdapter.data[index]
//            item.isRight = if (right) "1" else "0"
            item.isRight = right
//            item.answered = "1"
            item.answered = true
            mRadioTopicAdapter.notifyDataSetChanged()
        } else if (index < radioSize + multiSize) {
            // 多选题
            val item = mMultiTopicAdapter.data[index - radioSize]
//            item.isRight = if (right) "1" else "0"
            item.isRight = right
//            item.answered = "1"
            item.answered = true
            mMultiTopicAdapter.notifyDataSetChanged()
        } else if (index < topicTotal) {
            // 判断题
            val item = mJudgeTopicAdapter.data[index - radioSize - multiSize]
//            item.isRight = if (right) "1" else "0"
            item.isRight = right
//            item.answered = "1"
            item.answered = true
            mJudgeTopicAdapter.notifyDataSetChanged()
        }
    }

    @SuppressLint("SetTextI18n")
    private fun updateAnsweredProgress(topicTotal: Int) {
        viewBinding.rightCount.text = "$mRightCnt"
        viewBinding.errorCount.text = "$mErrorCnt"
        viewBinding.currentTopic.text = "${mRightCnt + mErrorCnt}/${topicTotal}"
    }

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

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

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

    private var mPractiseId: String? = null

    @SuppressLint("SetTextI18n")
    private fun updateViews(data: ExamTopic?) {
        data?.let {
            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)
            }

            val topicTotal = it.radioList.size + it.multiList.size + it.judgeList.size
            firstSelectItem?.let { firstItem ->
                queryPaperQuDetail(1, topicTotal, firstItem.practiseId, firstItem.quId)
            }
            updateAnsweredProgress(topicTotal)
        }
    }

    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) {
        finish()
    }

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

}

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

    var indexOffsite = 0

    var selectItemId: String? = null

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

    private fun itemBgResource(answered: Boolean, isRight: Boolean, id: String): Int {
        RcLog.info("=======selectItemId $selectItemId  id=$id  answered=$answered  isRight=$isRight")
        return when {
            id == selectItemId ->
                R.drawable.circle_radius_10_blue
//            "1" == answered -> {
            answered -> {
//                if ("1" == isRight)
                if (isRight)
                    R.drawable.circle_radius_10_blue_20p
                else
                    R.drawable.circle_radius_10_ffdada
            }
            else ->
                R.drawable.circle_radius_10_a2
        }
    }

}