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 androidx.core.content.ContextCompat
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.SuggestionActivity
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.constant.ItemViewType
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.databinding.FragmentSearchResultBinding
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.SettingsEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.suggest.SuggestType
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 SearchGameIndexFragment : ListFragment<GameEntity, SearchGameResultViewModel>() {

    private var mAdapter: SearchGameIndexAdapter? = null
    private var mExposureListener: ExposureListener? = null
    private val mBinding by lazy { FragmentSearchResultBinding.inflate(layoutInflater) }

    private var mKey: String = ""
    private var mType: String = ""

    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 getItemDecoration() = null

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

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

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

    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!!)
        mListRv.clearOnScrollListeners() // 不需要分页
        mListRv.addOnScrollListener(mExposureListener!!)
        mBinding.reuseNoneData.reuseNoDataSkipGameTv.visibility = View.VISIBLE
        mBinding.reuseNoneData.reuseNoDataSkipFunctionTv.visibility = View.VISIBLE
        mBinding.reuseNoneData.reuseNoDataSkipGameTv.setOnClickListener(this)
        mBinding.reuseNoneData.reuseNoDataSkipFunctionTv.setOnClickListener(this)
    }

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

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

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

    override fun onResume() {
        if (isEverPause && mAdapter != null) mAdapter?.notifyDataSetChanged()
        super.onResume()
        DownloadManager.getInstance().addObserver(dataWatcher)
    }

    override fun onPause() {
        super.onPause()
        DownloadManager.getInstance().removeObserver(dataWatcher)
    }

    override fun onLoadEmpty() {
        super.onLoadEmpty()
        val ad = AdHelper.getAd(AdHelper.LOCATION_SEARCH_EMPTY)
        if (ad != null) {
            showAd(ad)
        }

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

    private fun showAd(ad: SettingsEntity.AD) {
        val spannableString = SpannableString(ad.title)
        val clickableSpan = object : ClickableSpan() {
            override fun onClick(widget: View) {
                MtaHelper.onEvent("广告位统计", "搜索结果为空", ad.title)
                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)
        mBinding.reuseNoneData.reuseNoneDataDescTv.movementMethod = LinkMovementMethod.getInstance()
        mBinding.reuseNoneData.reuseNoneDataDescTv.text = spannableString
    }

    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)
    }

    // 下载被删除事件
    @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) &&
                mAdapter?.getItemViewType(gameAndPosition.value) == ItemViewType.GAME_NORMAL
            ) {
                val targetView = mLayoutManager.findViewByPosition(gameAndPosition.value)
                if (targetView != null) {
                    DialogUtils.showUnzipFailureDialog(requireContext(), downloadEntity)
                    return
                }
            }
        }
    }
}