package com.gh.gamecenter.search.fragment

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.View
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.DirectUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.base.fragment.LazyFragment
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.utils.toArrayList
import com.gh.gamecenter.common.view.FixLinearLayoutManager
import com.gh.gamecenter.databinding.FragmentSearchGameListBinding
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
import com.gh.gamecenter.livedata.EventObserver
import com.gh.gamecenter.search.adapter.SearchGameListAdapter
import com.gh.gamecenter.search.viewmodel.SearchGameListViewModel
import com.gh.gamecenter.search.viewmodel.SearchTabViewModel

class SearchGameListFragment : LazyFragment() {

    private val viewModel by viewModels<SearchGameListViewModel>()

    private val parentViewModel by viewModels<SearchTabViewModel>(
        ownerProducer = { parentFragment ?: this }
    )

    private var searchKey = ""
    private var searchType = ""
    private var location: String = ""

    private lateinit var binding: FragmentSearchGameListBinding

    private val adapter by lazy(LazyThreadSafetyMode.NONE) {
        SearchGameListAdapter(viewModel, location)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        location = arguments?.getString(EntranceConsts.KEY_LOCATION, "") ?: ""
        super.onCreate(savedInstanceState)
    }


    override fun getRealLayoutId(): Int = R.layout.fragment_search_game_list

    override fun onRealLayoutInflated(inflatedView: View) {
        binding = FragmentSearchGameListBinding.bind(inflatedView)
    }

    @SuppressLint("NotifyDataSetChanged")
    override fun initRealView() {
        super.initRealView()
        parentViewModel.searchKeyAndType.observe(viewLifecycleOwner) { (key, type) ->
            this.searchKey = key
            this.searchType = type
            // 清空上一次的搜索结果
            adapter.submitList(null)
            // 上面调用了 adapter.submitList(null) ，这里为什么还要调用 notifyDataSetChanged 呢？
            // 因为adapter.submitList(null)最终调用的adapter.notifyItemRangeRemoved()方法更新RecyclerView
            // 此方法不会立马清空RecyclerView 的内容，而是在postOnAnimation执行相关的移除工作，这里为了让RecyclerView的内容立马清空，需要再次调用adapter.notifyDataSetChanged()
            adapter.notifyDataSetChanged()
            viewModel.loadFirstData(key, type, location)
        }
        binding.rvGameList.layoutManager = FixLinearLayoutManager(context)
        binding.rvGameList.adapter = adapter

        binding.reuseNoData.reuseResetLoadTv.setOnClickListener {
            viewModel.retry()
        }
        binding.reuseNoConnection.connectionReloadTv.setOnClickListener {
            viewModel.retry()
        }

        binding.rvGameList.addOnScrollListener(ExposureListener(this, adapter))
        with(viewModel) {
            loadStatus.observe(viewLifecycleOwner) {
                binding.rvGameList.goneIf(it == LoadStatus.INIT_LOADING || it == LoadStatus.INIT_FAILED || it == LoadStatus.INIT_EMPTY)
                binding.reuseNoConnection.root.goneIf(it != LoadStatus.INIT_FAILED)
                binding.reuseLoading.root.goneIf(it != LoadStatus.INIT_LOADING)
                binding.reuseNoData.root.goneIf(it != LoadStatus.INIT_EMPTY)
                adapter.updateStatus(it)
            }

            dataList.observe(viewLifecycleOwner, Observer {
                adapter.submitList(it, searchKey, searchType)
            })

            gameDetailDestination.observe(viewLifecycleOwner, EventObserver {
                GameDetailActivity.startGameDetailActivity(
                    requireContext(),
                    it,
                    BaseActivity.mergeEntranceAndPath(location, "游戏单搜索"),
                    null
                )
            })

            homeDestination.observe(viewLifecycleOwner, EventObserver {
                DirectUtils.directToHomeActivity(
                    requireContext(),
                    it,
                    0,
                    location,
                    "游戏单搜索"
                )
            })

            gameCollectionDetailDestination.observe(viewLifecycleOwner, EventObserver { (itemId, exposureSourceList) ->
                startActivity(
                    GameCollectionDetailActivity.getIntent(
                        context = requireContext(),
                        itemId,
                        topCommentId = "",
                        exposureSourceList = exposureSourceList.toArrayList(),
                        entrance = "游戏单搜索"
                    )
                )
            })
        }
    }
}