package com.gh.gamecenter.search

import android.os.Bundle
import android.text.SpannableString
import android.text.Spanned
import android.text.TextPaint
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.view.View
import android.view.animation.Animation
import android.view.animation.TranslateAnimation
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.*
import com.gh.common.xapk.XapkInstaller
import com.gh.common.xapk.XapkUnzipStatus
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.SearchType
import com.gh.gamecenter.common.baselist.ListFragment
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.entity.SuggestType
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.databinding.FragmentSearchResultBinding
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Util_System_Keyboard
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class SearchGameResultFragment : ListFragment<GameEntity, SearchGameResultViewModel>() {

    private var mAdapter: SearchGameResultAdapter? = null
    private var mExposureListener: ExposureListener? = null
    private lateinit var mShowAction: Animation
    private lateinit var mHideAction: Animation
    private var mIsFirstLoad = true
    private val mBinding by lazy { FragmentSearchResultBinding.inflate(layoutInflater) }

    private var mKey: String = ""
    private var mType: String = ""
    private var mLoadingAnimation = false
    private var mScrollIng = false

    private val dataWatcher = object : DataWatcher() {
        override fun onDataChanged(downloadEntity: DownloadEntity) {
            mAdapter?.notifyItemByDownload(downloadEntity)

            if (downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS] == XapkUnzipStatus.FAILURE.name) {
                showUnzipFailureDialog(downloadEntity)
            }
        }

        override fun onDataInit(downloadEntity: DownloadEntity) {
            mAdapter?.notifyItemByDownload(downloadEntity)
        }
    }

    override fun getLayoutId() = 0
    override fun getInflatedLayout() = mBinding.root

    override fun provideListViewModel() = viewModelProvider<SearchGameResultViewModel>().apply { key = mKey }

    override fun provideListAdapter(): SearchGameResultAdapter {
        if (mAdapter == null) {
            mAdapter =
                SearchGameResultAdapter(requireContext(), this, mListViewModel, mEntrance, mType).apply { key = mKey }
        }
        return mAdapter!!
    }

    override fun getItemDecoration() = null

    override fun onCreate(savedInstanceState: Bundle?) {
        if (savedInstanceState != null) {
            mKey = savedInstanceState.getString(EntranceConsts.KEY_SEARCHKEY) ?: ""
            mType = savedInstanceState.getString(SearchActivity.KEY_SEARCH_TYPE) ?: ""
        }

        super.onCreate(savedInstanceState)
        mListRefresh?.isEnabled = false
        mBinding.reuseNoneData.reuseNoneDataDescTv.visibility = View.VISIBLE
        mBinding.reuseNoneData.reuseNoneDataTv.setText("没有找到你的游戏~")
        mBinding.reuseNoneData.reuseNoneData.setBackgroundColor(R.color.background_white.toColor(requireContext()))
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mExposureListener = ExposureListener(this, mAdapter!!)
        mBinding.reuseNoneData.reuseNoDataSkipFunctionTv.visibility = View.VISIBLE
        mBinding.reuseNoneData.reuseNoDataSkipGameTv.visibility = View.VISIBLE
        arrayListOf(
            mBinding.reuseNoneData.reuseNoDataSkipFunctionTv,
            mBinding.reuseNoneData.reuseNoDataSkipGameTv,
            mBinding.containerMenuClose,
            mBinding.containerMenuOpen,
            mBinding.seekFunctionBtn,
            mBinding.seekGameBtn
        ).forEach {
            it.setOnClickListener(this)
        }

        mListRv!!.addOnScrollListener(mExposureListener!!)
        mListRv!!.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    mScrollIng = false
                    mBinding.containerMenuClose.alpha = 1F
                } else {
                    mScrollIng = true
                    if (mBinding.containerMenuClose.visibility == View.VISIBLE) {
                        mBinding.containerMenuClose.alpha = 0.5F
                    } else {
                        mBinding.containerMenuClose.postDelayed({
                            mBinding.containerMenuClose.alpha = 0.5F
                        }, 300)
                    }
                }
            }

            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                if (mIsFirstLoad) {
                    mIsFirstLoad = false
                    val position = mLayoutManager?.findLastVisibleItemPosition()
                    if (position == (mAdapter?.itemCount ?: 0) - 1) {
                        val child = mLayoutManager?.findViewByPosition(position)
                        if (child != null && recyclerView.bottom - child.bottom > -DisplayUtils.dip2px(50F) && mAdapter?.isLoadOver() == true) {
                            return
                        }
                    }
                    mBinding.containerMenuOpen.visibility = View.VISIBLE
                    mBinding.seekGameBtn.visibility = View.VISIBLE
                    mBinding.seekFunctionBtn.visibility = View.VISIBLE
                    return
                }
                if (mBinding.containerMenuOpen.visibility == View.VISIBLE && !mLoadingAnimation) {
                    showCloseMenuView()
                }
                handleCloseMenuVisibility(recyclerView)
            }
        })

        initAnimation()
    }

    private fun handleCloseMenuVisibility(recyclerView: RecyclerView) {
        val position = mLayoutManager!!.findLastVisibleItemPosition()
        if (position == mAdapter!!.itemCount - 1) {
            val child = mLayoutManager!!.findViewByPosition(position)
            if (child != null && recyclerView.bottom - child.bottom > -DisplayUtils.dip2px(50F) && mAdapter?.isLoadOver() == true) {
                mBinding.containerMenuClose.visibility = View.GONE
            } else {
                mBinding.containerMenuClose.visibility = View.VISIBLE
            }
        } else {
            if (!mLoadingAnimation) mBinding.containerMenuClose.visibility = View.VISIBLE
        }
    }

    private fun initAnimation() {
        mShowAction = TranslateAnimation(
            Animation.RELATIVE_TO_SELF,
            1.0F, Animation.RELATIVE_TO_SELF, 0.0F,
            Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_SELF,
            0.0F
        )
        mShowAction.duration = 300
        mShowAction.setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationStart(animation: Animation?) {
                mLoadingAnimation = true
                mBinding.containerMenuClose.background = null
                mBinding.blank.visibility = View.VISIBLE
                mBinding.menuView.setImageResource(R.drawable.ic_search_menu_selected)
            }

            override fun onAnimationRepeat(animation: Animation?) {}

            override fun onAnimationEnd(animation: Animation?) {
                mLoadingAnimation = false
                mBinding.containerMenuClose.visibility = View.GONE
                mBinding.seekFunctionBtn.postDelayed({
                    mBinding.seekFunctionBtn.visibility = View.VISIBLE
                }, 100)
                mBinding.seekGameBtn.postDelayed({
                    mBinding.seekGameBtn.visibility = View.VISIBLE
                }, 130)
            }
        })

        mHideAction = TranslateAnimation(
            Animation.RELATIVE_TO_SELF,
            0.0F, Animation.RELATIVE_TO_SELF, 1.0F,
            Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_SELF,
            0.0F
        )
        mHideAction.duration = 300
        mHideAction.setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationStart(animation: Animation?) {
                mLoadingAnimation = true

                mBinding.containerMenuClose.visibility = View.VISIBLE
                mBinding.seekGameBtn.visibility = View.INVISIBLE
                mBinding.seekFunctionBtn.visibility = View.INVISIBLE
                mBinding.containerMenuClose.postDelayed({
                    mBinding.blank.visibility = View.GONE
                    mBinding.containerMenuClose.setBackgroundResource(R.drawable.bg_search_menu)
                    mBinding.menuView.setImageResource(R.drawable.ic_search_menu_unselect)
                    mBinding.containerMenuOpen.visibility = View.GONE
                }, 200)
            }

            override fun onAnimationRepeat(animation: Animation?) {}

            override fun onAnimationEnd(animation: Animation?) {
                mLoadingAnimation = false
            }
        })
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)

        outState.putString(EntranceConsts.KEY_SEARCHKEY, mKey)
        outState.putString(SearchActivity.KEY_SEARCH_TYPE, mType)
    }

    private fun showOpenMenuView() {
        mBinding.containerMenuOpen.startAnimation(mShowAction)
        mBinding.containerMenuOpen.visibility = View.VISIBLE
    }

    private fun showCloseMenuView() {
        mBinding.containerMenuOpen.startAnimation(mHideAction)
    }

    override fun onClick(view: View) {
        when (view.id) {
            R.id.reuseNoDataSkipFunctionTv -> {
                Util_System_Keyboard.hideSoftKeyboard(requireActivity())
                MtaHelper.onEvent("游戏搜索", "求功能", mKey)
                LogUtils.uploadSearchGame("ask_more_func", "搜索页", mKey, SearchType.fromString(mType).toChinese())
                HelpAndFeedbackBridge.startSuggestionActivity(context, SuggestType.functionSuggest, "", "求功能：$mKey")
            }

            R.id.reuseNoDataSkipGameTv -> {
                Util_System_Keyboard.hideSoftKeyboard(requireActivity())
                MtaHelper.onEvent("游戏搜索", "求游戏", mKey)
                LogUtils.uploadSearchGame("ask_more_games", "搜索页", mKey, SearchType.fromString(mType).toChinese())
                HelpAndFeedbackBridge.startSuggestionActivity(context, SuggestType.gameCollect, "", "求游戏：$mKey")
            }

            R.id.container_menu_close -> {
                if (mScrollIng) return
                LogUtils.uploadSearchGame("open_floating_window", "搜索页", mKey, SearchType.fromString(mType).toChinese())
                showOpenMenuView()
            }

            R.id.container_menu_open -> {
                if (mScrollIng) return
                LogUtils.uploadSearchGame(
                    "close_floating_window",
                    "搜索页",
                    mKey,
                    SearchType.fromString(mType).toChinese()
                )
                showCloseMenuView()
            }

            R.id.seek_game_btn -> {
                Util_System_Keyboard.hideSoftKeyboard(requireActivity())
                MtaHelper.onEvent("游戏搜索", "求游戏", mKey)
                LogUtils.uploadSearchGame("ask_more_games", " 搜索页-悬浮按钮", mKey, SearchType.fromString(mType).toChinese())
                HelpAndFeedbackBridge.startSuggestionActivity(context, SuggestType.gameCollect, "", "求游戏：$mKey")
                showCloseMenuView()
            }

            R.id.seek_function_btn -> {
                Util_System_Keyboard.hideSoftKeyboard(requireActivity())
                MtaHelper.onEvent("游戏搜索", "求功能", mKey)
                LogUtils.uploadSearchGame("ask_more_func", " 搜索页-悬浮按钮", mKey, SearchType.fromString(mType).toChinese())
                HelpAndFeedbackBridge.startSuggestionActivity(context, SuggestType.functionSuggest, "", "求功能：$mKey")
                showCloseMenuView()
            }
        }
    }

    override fun onResume() {
        super.onResume()
        DownloadManager.getInstance().addObserver(dataWatcher)
    }

    override fun onPause() {
        super.onPause()
        DownloadManager.getInstance().removeObserver(dataWatcher)
        if (mBinding.containerMenuOpen.visibility == View.VISIBLE) {
            showCloseMenuView()
        }
    }

    override fun onLoadEmpty() {
        super.onLoadEmpty()
        showAd(mBinding.reuseNoneData.reuseNoneDataDescTv, false)

        NewLogUtils.logSearchEmpty(SearchType.fromString(mType).toChinese(), mKey)
    }

    fun setParams(key: String, type: String) {
        this.mKey = key
        this.mType = type
        mAdapter?.key = key
        mListViewModel?.key = key
        mListViewModel?.mSearchSubjects?.clear()
        mListViewModel?.load(LoadType.REFRESH)
    }

    fun showAd(view: TextView?, isSearchList: Boolean) {
        if (isSearchList) {
            view?.visibility = View.GONE
            return
        } else {
            view?.visibility = View.VISIBLE
        }

        val ad = AdHelper.getAd(AdHelper.LOCATION_SEARCH_EMPTY) ?: return
        val spannableString = SpannableString(ad.title)
        val clickableSpan = object : ClickableSpan() {
            override fun onClick(widget: View) {
                MtaHelper.onEvent("广告位统计", "搜索结果为空", ad.title)
                MtaHelper.onEvent("游戏搜索", ad.title, mKey)
                LogUtils.uploadSearchGame("click_ad", " 搜索页", mKey, SearchType.fromString(mType).toChinese())
                DirectUtils.directToLinkPage(requireContext(), ad.toLinkEntity(), "(搜索结果为空-广告位)", "")
            }

            override fun updateDrawState(paint: TextPaint) {
                paint.isUnderlineText = false
                paint.color = ContextCompat.getColor(requireContext(), R.color.theme)
            }
        }
        val tempString = spannableString.toString()
        val start = tempString.indexOf(ad.title!!)
        spannableString.setSpan(clickableSpan, start, spannableString.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
        view?.movementMethod = LinkMovementMethod.getInstance()
        view?.text = spannableString
    }

    // 下载被删除事件
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(status: EBDownloadStatus) {
        if ("delete" == status.status) {
            mAdapter?.notifyItemAndRemoveDownload(status)
        }
    }

    // 安装/卸载 事件
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(busFour: EBPackage) {
        if (busFour.isInstalledOrUninstalled()) {
            mAdapter?.notifyDataSetChanged()
        }
    }

    fun showUnzipFailureDialog(downloadEntity: DownloadEntity) {
        val data = mAdapter?.positionAndPackageMap ?: return
        for (gameAndPosition in data) {
            if (gameAndPosition.key.contains(downloadEntity.packageName)) {
                val targetView = mLayoutManager.findViewByPosition(gameAndPosition.value)
                if (targetView != null) {
                    DialogUtils.showUnzipFailureDialog(requireContext(), downloadEntity)
                    return
                }
            }
        }
    }
}