package com.gh.gamecenter.feedback.view.suggest

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.Intent
import android.os.Bundle
import android.preference.PreferenceManager
import android.text.Html
import android.view.View
import android.view.Window
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.doOnTextChanged
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
import com.gh.gamecenter.common.constant.CommonConsts
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.common.entity.SuggestType
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.choosepic.ChoosePicAdapter
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.feature.entity.SettingsEntity
import com.gh.gamecenter.feature.view.dialog.SelectGameDialogFragment
import com.gh.gamecenter.feature.view.dialog.SelectGameViewModel
import com.gh.gamecenter.feedback.R
import com.gh.gamecenter.feedback.databinding.FragmentSuggestGameBinding
import com.gh.gamecenter.feedback.entity.ContactType
import com.gh.gamecenter.feedback.utils.NewFlatLogUtils

/***
 * 意见反馈-游戏问题
 */
class SuggestGameFragment : SuggestAppFragment() {
    private var mGameEntity: SimpleGameEntity? = null
    private var mIsPlugin = false
    private var mIsSmoothGame = false
    private lateinit var mBinding: FragmentSuggestGameBinding
    private lateinit var mSelectGameViewModel: SelectGameViewModel

    override fun getLayoutId(): Int = 0

    override fun getInflatedLayout(): View =
        FragmentSuggestGameBinding.inflate(layoutInflater, null, false).apply { mBinding = this }.root

    override fun getSuggestType(): String = SuggestType.GAME.type

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mGameEntity = arguments?.getParcelable(SimpleGameEntity::class.java.simpleName)
        mIsPlugin = arguments?.getBoolean(EntranceConsts.KEY_PLUGIN, false) ?: false
        mIsSmoothGame = arguments?.getBoolean(EntranceConsts.KEY_SMOOTH_GAME, false) ?: false
        mSelectGameViewModel = viewModelProviderFromParent()
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initSuggestHintType()
    }

    override fun initView() {
        mBinding.run {
            problemType.titleTv.text = Html.fromHtml(getString(R.string.suggestion_problem_type))
            selectProblem.titleTv.text = "选择问题"
            selectGame.titleTv.text = Html.fromHtml(getString(R.string.suggestion_select_game))
            problemDes.titleTv.text = Html.fromHtml(getString(R.string.suggestion_problem_des))

            problemType.expandIv.setOnClickListener {
                problemType.root.layoutParams = problemType.root.layoutParams.apply {
                    height = if (mIsProblemTypeExpand) 48F.dip2px() else LinearLayout.LayoutParams.WRAP_CONTENT
                }
                problemType.expandIv.rotation = if (mIsProblemTypeExpand) 0F else 180F
                mIsProblemTypeExpand = !mIsProblemTypeExpand
            }

            selectProblem.expandIv.setOnClickListener {
                selectProblem.root.layoutParams = selectProblem.root.layoutParams.apply {
                    height = if (mIsSelectProblemExpand) 48F.dip2px() else LinearLayout.LayoutParams.WRAP_CONTENT
                }
                selectProblem.expandIv.rotation = if (mIsSelectProblemExpand) 0F else 180F
                mIsSelectProblemExpand = !mIsSelectProblemExpand
            }

            selectGame.root.setOnClickListener {
                SelectGameDialogFragment.show(
                    (requireActivity() as AppCompatActivity),
                    this@SuggestGameFragment::class.java.name
                )
            }

            problemDes.run {
                editText.doOnTextChanged { text, _, _, _ ->
                    val count = text?.count { !it.isWhitespace() } ?: 0
                    problemDes.countTv.text = "${count}/300"
                }
            }

            uploadPic.run {
                picRv.layoutManager = mUploadPicLayoutManager
                mPicAdapter = ChoosePicAdapter(requireContext(), mUploadPicListClickListener)
                picRv.adapter = mPicAdapter
            }

            contact.contactTv.setOnClickListener {
                showContactOptionPopup(it) { name ->
                    mViewModel.contactType = ContactType.getContactTypeByName(name)
                    contact.contactTv.text = name
                }
            }

            suggestPostBtn.setOnClickListener {
                val isSelectedProblemType = mViewModel.selectedProblemType != null
                val isSelectedGame = mViewModel.selectedGameInfo.isNotEmpty()
                val isProblemDesNotEmpty = problemDes.editText.text.trim().isNotEmpty()

                if (problemType.root.visibility == View.VISIBLE && !isSelectedProblemType) {
                    toast("请选择问题类型")
                    return@setOnClickListener
                }

                if (!isSelectedGame) {
                    toast("请选择游戏")
                    return@setOnClickListener
                }

                if (!isProblemDesNotEmpty) {
                    toast("请填写问题描述")
                    return@setOnClickListener
                }

                ifLogin("意见反馈-${getSuggestType()}") {
                    var selectedProblem = ""
                    mViewModel.selectedProblemSet.forEachIndexed { index, problem ->
                        if (index == 0) {
                            selectedProblem = problem
                        } else {
                            selectedProblem += "+$problem"
                        }
                    }
                    NewFlatLogUtils.logFeedbackCommit(
                        getSuggestType(),
                        mViewModel.selectedProblemType?.name ?: "",
                        selectedProblem
                    )

                    mPostDialog = WaitingDialogFragment.newInstance(getString(R.string.dialog_feedback_doing))
                    mPostDialog?.show(childFragmentManager, null)

                    val fileList = mPicAdapter?.fileList
                    if (fileList.isNullOrEmpty()) {
                        mViewModel.postNormalSuggestion(
                            contact.contactEt.text.toString().trim(),
                            problemDes.editText.text.toString().trim()
                        )
                    } else {
                        mViewModel.uploadPicAndPostNormalSuggestion(
                            fileList,
                            mPostDialog,
                            contact.contactEt.text.toString().trim(),
                            problemDes.editText.text.toString().trim()
                        )
                    }
                }
            }
        }
    }

    override fun observerData() {
        mViewModel.problemTypeLiveData.observeNonNull(this) {
            mBinding.problemType.flexbox.removeAllViews()
            mProblemTypeItemViewList.clear()
            mBinding.problemType.root.goneIf(it.size < 2)

            var autoSelectedIndex = -1
            it.forEachIndexed { index, problemType ->
                val item = getProblemTypeItemView(problemType)
                mProblemTypeItemViewList.add(item)
                mBinding.problemType.flexbox.addView(item)
                item.tag = problemType.name
                toggleHighlightedView(item, mViewModel.selectedProblemType?.id == problemType.id)
                item.setOnClickListener {
                    mProblemTypeCheckedIndex = if (mViewModel.selectedProblemType?.id == problemType.id) -1 else index
                    mViewModel.selectedProblemType =
                        if (mViewModel.selectedProblemType?.id == problemType.id) null else problemType
                    mViewModel.selectedProblemSet.clear()
                    toggleHighlightedView(item, mViewModel.selectedProblemType?.id == problemType.id)
                    for (view in mProblemTypeItemViewList) {
                        if (view != item) toggleHighlightedView(view, false)
                    }
                    mBinding.selectProblem.descTv.visibility = View.GONE
                    mViewModel.getProblemList()
                }
                if (mIsPlugin && problemType.name.contains("插件问题")) {
                    autoSelectedIndex = index
                } else if (mIsSmoothGame && problemType.name.contains("畅玩问题")) {
                    autoSelectedIndex = index
                }
            }
            mBinding.problemType.flexbox.post {
                mBinding.problemType.expandIv.goneIf(mBinding.problemType.flexbox.flexLines.size < 2)
                if (autoSelectedIndex != -1) {
                    mProblemTypeItemViewList.safelyGetInRelease(autoSelectedIndex)?.performClick()
                }
            }
        }

        mViewModel.problemLiveData.observeNonNull(this) {
            mBinding.selectProblem.flexbox.removeAllViews()
            it.forEach { problem ->
                val item = getProblemTypeItemView(problem)
                mBinding.selectProblem.flexbox.addView(item)
                item.tag = problem.name
                toggleHighlightedView(item, mViewModel.selectedProblemSet.contains(problem.id))
                item.setOnClickListener {
                    toggleHighlightedView(item, !mViewModel.selectedProblemSet.contains(problem.id))
                    mBinding.selectProblem.descTv.text = problem.remark
                    mBinding.selectProblem.descTv.goneIf(
                        problem.remark.isEmpty() || mViewModel.selectedProblemSet.contains(
                            problem.id
                        )
                    )
                    mBinding.selectProblem.root.layoutParams = mBinding.selectProblem.root.layoutParams.apply {
                        height =
                            if ((problem.remark.isNotEmpty() && !mViewModel.selectedProblemSet.contains(problem.id)) || mIsSelectProblemExpand)
                                LinearLayout.LayoutParams.WRAP_CONTENT
                            else
                                48F.dip2px()
                    }
                    if (mViewModel.selectedProblemSet.contains(problem.id)) {
                        mViewModel.selectedProblemSet.remove(problem.id)
                    } else {
                        mViewModel.selectedProblemSet.add(problem.id)
                    }
                }
            }
            mBinding.selectProblem.root.goneIf(it.isEmpty())
            mBinding.problemType.divider.goneIf(it.isNotEmpty())
            mBinding.selectProblem.flexbox.post {
                mBinding.selectProblem.expandIv.goneIf(mBinding.selectProblem.flexbox.flexLines.size < 2)
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (data != null && requestCode == SelectGameDialogFragment.REQUEST_CODE_SELECT_GAME && resultCode == Activity.RESULT_OK) {
            mBinding.selectGame.selectTv.text = data.getStringExtra(EntranceConsts.KEY_GAME_NAME)
            mViewModel.selectedGameName = data.getStringExtra(EntranceConsts.KEY_GAME_NAME) ?: ""
            mViewModel.selectedGameInfo = data.getStringExtra(EntranceConsts.KEY_GAME_INFO) ?: ""
        }
    }

    override fun handleBackPressed(): Boolean {
        mBinding.run {
            if (mViewModel.selectedProblemType != null ||
                mViewModel.selectedGameName.isNotEmpty() ||
                problemDes.editText.text.isNotEmpty() ||
                !mPicAdapter?.fileList.isNullOrEmpty() ||
                contact.contactEt.text.isNotEmpty()
            ) {
                DialogHelper.showDialog(
                    requireContext(), "提示",
                    "确定放弃反馈吗？", "继续反馈", "放弃", cancelClickCallback = {
                        mIsBackConfirm = true
                        requireActivity().onBackPressed()
                    }, extraConfig = DialogHelper.Config(centerContent = true, centerTitle = true)
                )
                return true
            } else {
                return false
            }
        }
    }

    private fun initSuggestHintType() {
        if (mGameEntity != null) {
            mBinding.selectGame.selectTv.text = mGameEntity!!.name
            mViewModel.selectedGameName = mGameEntity!!.name
            mViewModel.selectedGameInfo = mGameEntity!!.name
        }
        if (mSuggestContent.isNotEmpty()) {
            mBinding.problemDes.editText.setText(mSuggestContent)
            mBinding.problemDes.editText.setSelection(mBinding.problemDes.editText.text.length)
        }

        val suggestionType = PreferenceManager.getDefaultSharedPreferences(requireContext())
            .getString(CommonConsts.SUGGESTION_HINT_TYPE, null)
        if (mSuggestHintType.isNotEmpty() && !suggestionType.isNullOrEmpty()) {
            val typeEntity = GsonUtils.fromJson(
                suggestionType,
                SettingsEntity.Suggestion::class.java
            )
            when (mSuggestHintType) {
                EntranceConsts.KEY_PLUGIN -> {
                    val plugin = typeEntity.plugin
                    if (!plugin.isNullOrEmpty()) {
                        showHintDialog(plugin)
                    }
                }

                "local_game" -> {
                    val localGameList = typeEntity.localGame
                    if (!localGameList.isNullOrEmpty()) {
                        showHintDialog(localGameList)
                    }
                }

                "welfare_game" -> {
                    val welfareGame = typeEntity.welfareGame
                    if (!welfareGame.isNullOrEmpty()) {
                        showHintDialog(welfareGame)
                    }
                }

                "online_game" -> {
                    val onlineGame = typeEntity.onlineGame
                    if (!onlineGame.isNullOrEmpty()) {
                        showHintDialog(onlineGame)
                    }
                }

                "gjlocal_game" -> {
                    val internationalLocalGame = typeEntity.internationalLocalGame
                    if (!internationalLocalGame.isNullOrEmpty()) {
                        showHintDialog(internationalLocalGame)
                    }
                }

                "gjonline_game" -> {
                    val internationalOnlineGame = typeEntity.internationalOnlineGame
                    if (!internationalOnlineGame.isNullOrEmpty()) {
                        showHintDialog(internationalOnlineGame)
                    }
                }

                "libao" -> {
                    val libao = typeEntity.libao
                    if (!libao.isNullOrEmpty()) {
                        showHintDialog(libao)
                    }
                }

                "report" -> {
                    val report = typeEntity.report
                    if (!report.isNullOrEmpty()) {
                        showHintDialog(report)
                    }
                }

                "video" -> {
                    val video = typeEntity.video
                    if (!video.isNullOrEmpty()) {
                        showHintDialog(video)
                    }
                }
            }
        }
    }

    @SuppressLint("SetTextI18n")
    private fun showHintDialog(dialogType: List<String>) {
        val dialog = Dialog(requireContext())
        val container = LinearLayout(requireContext())
        container.orientation = LinearLayout.VERTICAL
        container.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(requireContext()))
        container.setPadding(0, 12F.dip2px(), 0, 12F.dip2px())
        for (s in dialogType) {
            val reportTv = TextView(requireContext())
            reportTv.text = s
            reportTv.textSize = 17F
            reportTv.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(requireContext()))
            reportTv.setBackgroundResource(com.gh.gamecenter.common.R.drawable.textview_white_style)
            val widthPixels = resources.displayMetrics.widthPixels
            reportTv.layoutParams =
                LinearLayout.LayoutParams(widthPixels * 9 / 10, LinearLayout.LayoutParams.WRAP_CONTENT)
            reportTv.setPadding(20F.dip2px(), 12F.dip2px(), 20F.dip2px(), 12F.dip2px())
            container.addView(reportTv)
            reportTv.setOnClickListener {
                dialog.cancel()
                mBinding.problemDes.editText.setText("${mBinding.problemDes.editText.text}${reportTv.text}")
                mBinding.problemDes.editText.setSelection(mBinding.problemDes.editText.text.length)
            }
        }
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog.setContentView(container)
        dialog.show()
    }

    override fun onDarkModeChanged() {
        for ((index, view) in mProblemTypeItemViewList.withIndex()) {
            toggleHighlightedView(view, index == mProblemTypeCheckedIndex)
        }
        for (i in 0 until mBinding.selectProblem.flexbox.childCount) {
            val problem = mViewModel.problemLiveData.value?.safelyGetInRelease(i) ?: return
            mBinding.selectProblem.flexbox.getChildAt(i)?.let {
                toggleHighlightedView(it, mViewModel.selectedProblemSet.contains(problem.id))
            }
        }
    }
}