package com.gh.gamecenter.gamedetail.accelerator.dialog

import android.content.Context
import android.graphics.Rect
import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseBottomDialogFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.databinding.DialogFragmentAcceleratorZoneBinding
import com.gh.gamecenter.databinding.RecyclerAcceleratorZoneBinding
import com.gh.gamecenter.feature.entity.AcctGameInfo
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.gamedetail.AcceleratorZoneViewModel
import com.gh.gamecenter.gamedetail.accelerator.GameDetailAcceleratorUiHelper.Companion.SCENE_TYPE_NO_GUIDE_LAYER
import com.gh.gamecenter.gamedetail.accelerator.chain.AcceleratorClient
import com.gh.gamecenter.gamedetail.accelerator.chain.AcceleratorValidator
import com.halo.assistant.accelerator.repository.AcceleratorDataHolder
import kotlin.math.roundToInt

class AcceleratorZoneDialogFragment : BaseBottomDialogFragment<DialogFragmentAcceleratorZoneBinding>() {

    private val viewModel by viewModels<AcceleratorZoneViewModel>()

    private lateinit var adapter: ZoneAdapter

    private var sourceEntrance = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        sourceEntrance = arguments?.getString(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: ""
    }


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

        val data =
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                arguments?.getParcelableArrayList(EntranceConsts.KEY_DATA, AcctGameInfo.ZoneInfo::class.java)
            } else {
                arguments?.getParcelableArrayList(EntranceConsts.KEY_DATA)
            } ?: listOf<AcctGameInfo.ZoneInfo>()

        val game = arguments?.getParcelable<GameEntity>(EntranceConsts.KEY_GAME)!!
        val selectedId = arguments?.getInt(KEY_SELECTED_ID) ?: -1

        mBinding.titleView.setOnRightClickListener {
            dismiss()
        }

        adapter = ZoneAdapter {
            startAccelerating(game, it)
            dismiss()
        }
        mBinding.recyclerZone.layoutManager = GridLayoutManager(requireContext(), 3)
        mBinding.recyclerZone.addItemDecoration(MyDecorationItem())
        mBinding.recyclerZone.adapter = adapter
        adapter.setData(selectedId, data)
    }

    private fun startAccelerating(game: GameEntity, zoneInfo: AcctGameInfo.ZoneInfo) {
        context?.let {
            viewModel.useCase.insertAcctGameInfo(AcctGameInfo(game.id, game.getUniquePackageName() ?: "", zoneInfo))
            val acceleratorDataHolder = AcceleratorDataHolder.instance
            val memberType = acceleratorDataHolder.memberType

            SensorsBridge.trackNetworkAccelerationButtonClick(
                game.getUniquePackageName() ?: "",
                game.id,
                game.name ?: "",
                memberType,
                zoneInfo.cnName ?: "",
                SCENE_TYPE_NO_GUIDE_LAYER,
                sourceEntrance
            )

            val request = AcceleratorValidator.Request(game, sourceEntrance)
            AcceleratorClient.newInstance()
                .execute(it, request, object : AcceleratorValidator.ValidateListener {
                    override fun finished(context: Context) {
                        StartingAcceleratorDialogFragment.show(
                            context,
                            zoneInfo,
                            game,
                            isNeedRecord = false,
                            hasMultiZone = true,
                            sourceEntrance = sourceEntrance
                        )
                    }

                })
        }

    }

    companion object {
        private const val KEY_SELECTED_ID = "key_selected_id"
        fun show(
            context: Context,
            selectedId: Int? = null,
            data: List<AcctGameInfo.ZoneInfo>,
            game: GameEntity,
            sourceEntrance: String
        ) {
            if (context is AppCompatActivity) {
                context.supportFragmentManager
            } else {
                (CurrentActivityHolder.getCurrentActivity() as? AppCompatActivity)?.supportFragmentManager
            }?.let {
                val fragment = AcceleratorZoneDialogFragment().apply {
                    arguments = Bundle().apply {
                        putParcelableArrayList(EntranceConsts.KEY_DATA, data.toArrayList())
                        putParcelable(EntranceConsts.KEY_GAME, game)
                        putInt(KEY_SELECTED_ID, selectedId ?: -1)
                        putString(EntranceConsts.KEY_SOURCE_ENTRANCE, sourceEntrance)
                    }
                }
                fragment.show(it, fragment::class.java.simpleName)
            }
        }
    }

    private class MyDecorationItem : RecyclerView.ItemDecoration() {

        override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
            val position = parent.getChildAdapterPosition(view)
            val space = (16F.dip2px() / 3F).roundToInt()
            val (left, right) = when (position % 3) {
                0 -> 0 to space
                1 -> space to space
                else -> space to 0
            }
            outRect.top = 8F.dip2px()
            outRect.left = left
            outRect.right = right
        }
    }

    class ZoneAdapter(private val click: (AcctGameInfo.ZoneInfo) -> Unit) :
        ListAdapter<AcctGameInfo.ZoneInfo, ZoneAdapter.ZoneViewHolder>(diffCallback) {

        private var selectedId = -1

        fun setData(selectedId: Int, data: List<AcctGameInfo.ZoneInfo>) {
            this.selectedId = selectedId
            submitList(data)
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ZoneViewHolder {
            return ZoneViewHolder(parent.toBinding())
        }

        override fun onBindViewHolder(holder: ZoneViewHolder, position: Int, payloads: MutableList<Any>) {
            if (payloads.isNotEmpty()) {
                updateSelectedState(holder, position)
            } else {
                super.onBindViewHolder(holder, position, payloads)
            }
        }

        override fun onBindViewHolder(holder: ZoneViewHolder, position: Int) {
            val item = getItem(position) ?: return
            updateSelectedState(holder, item.id)
            holder.binding.tvName.text = item.cnName
            holder.itemView.setOnClickListener {
                click(item)
            }
        }

        private fun updateSelectedState(holder: ZoneViewHolder, zoneId: Int) {
            val (textColorResId, backgroundResId) = if (selectedId == zoneId) {
                com.gh.gamecenter.common.R.color.text_theme to R.drawable.bg_shape_2496ff_alpha_10_radius_8
            } else {
                com.gh.gamecenter.common.R.color.text_secondary to R.drawable.bg_shape_f8_radius_8
            }
            holder.binding.tvName.setTextColor(textColorResId.toColor(holder.itemView.context))
            holder.binding.tvName.setBackgroundResource(backgroundResId)
        }

        companion object {

            private val diffCallback = object : DiffUtil.ItemCallback<AcctGameInfo.ZoneInfo>() {
                override fun areItemsTheSame(oldItem: AcctGameInfo.ZoneInfo, newItem: AcctGameInfo.ZoneInfo): Boolean {
                    return oldItem.id == newItem.id
                }

                override fun areContentsTheSame(
                    oldItem: AcctGameInfo.ZoneInfo,
                    newItem: AcctGameInfo.ZoneInfo
                ): Boolean {
                    return oldItem == newItem
                }

            }
        }

        class ZoneViewHolder(val binding: RecyclerAcceleratorZoneBinding) : ViewHolder(binding.root)
    }
}