package com.gh.gamecenter.gamecollection.choose

import android.os.Bundle
import android.view.MenuItem
import android.view.View
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.FragmentChooseGamesBinding
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.common.utils.toColor
import java.lang.ref.WeakReference
import java.util.*

class ChooseGamesFragment : ToolbarFragment(), ChooseGamesAdapter.ItemDragListener {

    private lateinit var mBinding: FragmentChooseGamesBinding
    private lateinit var mViewModel: ChooseGamesViewModel
    private lateinit var mAdapter: ChooseGamesAdapter
    private var mChooseGamesTemp: ArrayList<GameEntity> = arrayListOf()
    private val mItemTouchCallback = CustomItemTouchHelper(this)
    private val mItemTouchHelper = ItemTouchHelper(mItemTouchCallback)

    override fun getLayoutId(): Int = 0

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

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initMenu(R.menu.menu_save)
        mViewModel = viewModelProvider(ChooseGamesViewModel.Factory())
    }

    override fun onMenuItemClick(menuItem: MenuItem?) {
        super.onMenuItemClick(menuItem)
        menuItem?.run {
            if (itemId == R.id.layout_menu_save) {
                requireActivity().finish()
            }
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mChooseGamesTemp.clear()
        mChooseGamesTemp.addAll(mViewModel.chooseGamesLiveData.value ?: arrayListOf())
        mViewModel.chooseGamesLiveData.observe(viewLifecycleOwner) {
            mBinding.addGamesTv.goneIf(it.isNotEmpty())
            mBinding.gamesRv.goneIf(it.isEmpty())
            mAdapter.setListData(it)
            mBinding.gameCountTv.text = "已收录${it.size}款游戏"
        }
        mBinding.gamesRv.apply {
            layoutManager = LinearLayoutManager(requireContext())
            adapter = ChooseGamesAdapter(requireContext(), this@ChooseGamesFragment).apply {
                mAdapter = this
            }
            mItemTouchHelper.attachToRecyclerView(this)
        }

        mBinding.addGamesButton.setOnClickListener {
            requireContext().startActivity(AddGamesActivity.getIntent(requireContext()))
        }

        mBinding.addGamesTv.setOnClickListener { mBinding.addGamesButton.performClick() }

    }

    override fun startDragItem(holder: RecyclerView.ViewHolder) {
        mItemTouchHelper.startDrag(holder)
    }

    override fun setToTop(holder: RecyclerView.ViewHolder) {
        val holderPosition = holder.bindingAdapterPosition
        for (i in holderPosition downTo 1) {
            Collections.swap(mAdapter.entityList, i, i - 1)
            val games = mViewModel.chooseGamesLiveData.value ?: arrayListOf()
            Collections.swap(games, i, i - 1)
        }
        mAdapter.notifyDataSetChanged()
        mBinding.gamesRv.scrollToPosition(0)
    }

    override fun deleteItem(entity: GameEntity) {
        val chooseGames = mViewModel.chooseGamesLiveData.value
        chooseGames?.remove(entity)
        mViewModel.chooseGamesLiveData.postValue(chooseGames)
    }

    override fun onBackPressed(): Boolean {
        val chooseGames = mViewModel.chooseGamesLiveData.value
        if (!chooseGames.isNullOrEmpty() || !mChooseGamesTemp.isNullOrEmpty()) {
            DialogHelper.showDialog(requireContext(), "提示", "是否保存本次选择的游戏", "保存", "取消", {
                requireActivity().finish()
            }, {
                mViewModel.chooseGamesLiveData.postValue(mChooseGamesTemp)
                requireActivity().finish()
            }, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true))
            return true
        }
        return super.onBackPressed()
    }

    class CustomItemTouchHelper(val fragment: ChooseGamesFragment) : ItemTouchHelper.Callback() {

        var fragmentReference: WeakReference<ChooseGamesFragment> = WeakReference(fragment)

        override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
            return makeMovementFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0)
        }

        override fun onMove(
            recyclerView: RecyclerView,
            viewHolder: RecyclerView.ViewHolder,
            target: RecyclerView.ViewHolder
        ): Boolean {
            val fragment = fragmentReference.get()
            fragment?.run {
                mAdapter.notifyItemMoved(viewHolder.bindingAdapterPosition, target.bindingAdapterPosition)
                Collections.swap(mAdapter.entityList, viewHolder.bindingAdapterPosition, target.bindingAdapterPosition)
                val games = mViewModel.chooseGamesLiveData.value ?: arrayListOf()
                Collections.swap(games, viewHolder.bindingAdapterPosition, target.bindingAdapterPosition)
            }
            return true
        }

        override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {

        }

        override fun canDropOver(
            recyclerView: RecyclerView,
            current: RecyclerView.ViewHolder,
            target: RecyclerView.ViewHolder
        ): Boolean {
            return true
        }

        override fun isLongPressDragEnabled(): Boolean {
            return false
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        if (::mBinding.isInitialized) {
            mBinding.run {
                root.setBackgroundColor(R.color.background_white.toColor(requireContext()))
                gameCountTv.setTextColor(R.color.text_title.toColor(requireContext()))
                addGamesButton.setTextColor(R.color.theme_font.toColor(requireContext()))
                addGamesTv.setTextColor(R.color.text_body.toColor(requireContext()))
                gamesRv.adapter?.run { notifyItemRangeChanged(0, itemCount) }
            }
        }
    }
}