package com.gh.gamecenter

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.*
import androidx.core.widget.doAfterTextChanged
import androidx.core.widget.doOnTextChanged
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.common.util.*
import com.gh.common.util.LogUtils
import com.gh.gamecenter.DisplayType.*
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.db.SearchHistoryDao
import com.gh.gamecenter.eventbus.EBSearch
import com.gh.gamecenter.search.SearchDefaultFragment
import com.gh.gamecenter.search.SearchGameIndexFragment
import com.gh.gamecenter.search.SearchGameResultFragment
import com.lightgame.utils.Util_System_Keyboard
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.subjects.PublishSubject
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.concurrent.TimeUnit

open class SearchActivity : BaseActivity() {

    lateinit var searchEt: EditText
    lateinit var searchBtn: TextView
    lateinit var backBtn: RelativeLayout
    private lateinit var deleteIv: ImageView

    private var mDao: SearchHistoryDao? = null

    protected var mSearchKey: String? = null
    protected var mIsAutoSearchDisabled: Boolean = false

    protected var mSearchType = SearchType.DEFAULT
    protected var mDisplayType = DEFAULT

    private var mPublishSubject: PublishSubject<String>? = null

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putInt(KEY_DISPLAY_TYPE, mDisplayType.value)
        outState.putString(EntranceConsts.KEY_SEARCHKEY, mSearchKey)
        outState.putString(KEY_SEARCH_TYPE, mSearchType.value)
    }

    override fun getLayoutId(): Int {
        return R.layout.activity_search
    }

    @SuppressLint("CheckResult")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        updateStatusBarColor(R.color.background_white, R.color.background_white)

        searchEt = findViewById(R.id.searchEt)
        searchBtn = findViewById(R.id.searchBtn)
        deleteIv = findViewById(R.id.deleteIv)
        backBtn = findViewById(R.id.backBtn)

        val hint = intent.getStringExtra(EntranceConsts.KEY_HINT)
        val searchImmediately = intent.getBooleanExtra(KEY_SEARCH_IMMEDIATELY, false)
        var ignoreTextChanges = savedInstanceState != null

        mDao = SearchHistoryDao(this)
        mPublishSubject = PublishSubject.create()

        mPublishSubject!!
            .debounce(300, TimeUnit.MILLISECONDS)
            .distinctUntilChanged()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                if (searchEt.text.isNotEmpty()
                    && searchEt.text != searchEt.hint
                    && !ignoreTextChanges
                ) {
                    search(SearchType.AUTO, it)
                }

                ignoreTextChanges = false
            }

        initSearchBar()

        if (!TextUtils.isEmpty(hint)) {
            searchEt.hint = hint
            if (searchImmediately) {
                mDisplayType = GAME_DETAIL
                mDao?.add(hint)
                search(SearchType.DEFAULT, hint)
            }
        } else {
            searchEt.hint = HINT_TEXT
        }

        if (savedInstanceState == null
            && mDisplayType == DEFAULT
        ) {
            updateDisplayType(DEFAULT)
        }

        SensorsBridge.trackEvent(
            "SearchPageShow",
            "source_entrance",
            intent.getStringExtra(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: ""
        )
    }

    open fun initSearchBar() {
        // 进入获取焦点
        searchEt.post { searchEt.requestFocus() }

        searchEt.setOnEditorActionListener { _, actionId, _ ->
            if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                Util_System_Keyboard.hideSoftKeyboard(this)
                search(SearchType.MANUAL, null)
            }
            false
        }

        searchBtn.setOnClickListener {
            Util_System_Keyboard.hideSoftKeyboard(this)
            search(SearchType.MANUAL, null)
        }

        deleteIv.setOnClickListener {
            deleteIv.visibility = View.GONE
            searchEt.setText("")
        }

        searchEt.doOnTextChanged { text, _, _, _ -> deleteIv.goneIf(text?.length == 0) }
        searchEt.doAfterTextChanged { editable ->
            val newSearchKey = editable.toString().trim { it <= ' ' }
            if (newSearchKey.isEmpty()) {
                updateDisplayType(DisplayType.DEFAULT)
                mPublishSubject?.onNext(newSearchKey)
            } else if (!mIsAutoSearchDisabled) {
                mPublishSubject?.onNext(newSearchKey)
            }
        }
        searchEt.filters = arrayOf(TextHelper.getFilter(50, "最多输入50个字"))

        backBtn.setOnClickListener { onBackPressed() }
    }

    open fun search(type: SearchType, key: String?) {
        mSearchType = type
        mIsAutoSearchDisabled = true
        // 自动搜索，默认搜索，热门搜索，历史搜索，主动搜索
        when (type) {
            SearchType.AUTO -> handleAutoSearch(key)
            SearchType.DEFAULT -> handleDefaultSearch(key)
            SearchType.HOT -> handleHotSearch(key)
            SearchType.HISTORY -> handleHistorySearch(key)
            SearchType.MANUAL -> handleManualSearch()
        }
        mIsAutoSearchDisabled = false
    }

    private fun handleAutoSearch(key: String?) {
        val newSearchKey = searchEt.text.toString().trim { it <= ' ' }
        if (newSearchKey.isEmpty()) {
            val hint = searchEt.hint.toString()
            if (!TextUtils.isEmpty(hint) && HINT_TEXT != hint) {
                mDao?.add(hint)
                search(SearchType.DEFAULT, hint)
            }
        } else {
            mSearchKey = key
            updateDisplayType(GAME_DIGEST)
            LogUtils.uploadSearchGame("searching", "搜索页", key, "自动搜索")
            SensorsBridge.trackEvent("SearchButtonClick", "search_content", key ?: "", "search_type", "输入搜索")
        }
    }

    private fun handleDefaultSearch(key: String?) {
        mSearchKey = key
        searchEt.setText(key)
        searchEt.setSelection(searchEt.text.length)
        updateDisplayType(GAME_DETAIL)
        LogUtils.uploadSearchGame("searching", "搜索页", key, "默认搜索")
        SensorsBridge.trackEvent("SearchButtonClick", "search_content", key ?: "", "search_type", "默认搜索")
//        MtaHelper.onEvent("游戏搜索", "默认搜索", key)
    }

    private fun handleHotSearch(key: String?) {
        mSearchKey = key
        searchEt.setText(key)
        searchEt.setSelection(searchEt.text.length)
        updateDisplayType(GAME_DETAIL)
    }

    private fun handleHistorySearch(key: String?) {
        mSearchKey = key
        searchEt.setText(key)
        searchEt.setSelection(searchEt.text.length)
        updateDisplayType(GAME_DETAIL)
        LogUtils.uploadSearchGame("searching", "搜索页", key, "历史搜索")
        SensorsBridge.trackEvent("SearchButtonClick", "search_content", key ?: "", "search_type", "历史搜索")
//        MtaHelper.onEvent("游戏搜索", "历史搜索", key)
    }

    private fun handleManualSearch() {
        val newSearchKey = searchEt.text.toString().trim { it <= ' ' }
        if (newSearchKey.isEmpty()) {
            val hint = searchEt.hint.toString()
            if (!TextUtils.isEmpty(hint) && HINT_TEXT != hint) {
                mDao?.add(hint)
                search(SearchType.DEFAULT, hint)
            }
        } else if (newSearchKey != mSearchKey || mDisplayType != GAME_DETAIL) {
            mSearchKey = newSearchKey
            if (!TextUtils.isEmpty(mSearchKey)) {
                SensorsBridge.trackEvent("SearchButtonClick", "search_content", newSearchKey, "search_type", "输入搜索")
                mDao?.add(mSearchKey)
                updateDisplayType(GAME_DETAIL)
            } else {
                toast("请输入搜索内容")
            }
        }
        LogUtils.uploadSearchGame("searching", "搜索页", newSearchKey, "主动搜索")
//        MtaHelper.onEvent("游戏搜索", "主动搜索", newSearchKey)
    }

    open fun updateDisplayType(type: DisplayType) {
        val transaction = supportFragmentManager.beginTransaction()
        when (type) {
            DEFAULT -> {
                val fragment = supportFragmentManager.findFragmentByTag(SearchDefaultFragment::class.java.name)
                    ?: SearchDefaultFragment().apply {
                        arguments = Bundle().also { it.putBoolean(SearchDefaultFragment.KEY_IS_GAME_SEARCH, true) }
                    }
                transaction.replace(R.id.search_result, fragment, SearchDefaultFragment::class.java.name)
            }
            GAME_DIGEST -> {
                val digestListFragment =
                    supportFragmentManager.findFragmentByTag(SearchGameIndexFragment::class.java.name) as? SearchGameIndexFragment
                        ?: SearchGameIndexFragment()
                digestListFragment.setParams(mSearchKey ?: "", mSearchType.value)
                transaction.replace(R.id.search_result, digestListFragment, SearchGameIndexFragment::class.java.name)
            }
            GAME_DETAIL -> {
                val detailListFragment =
                    supportFragmentManager.findFragmentByTag(SearchGameResultFragment::class.java.name) as? SearchGameResultFragment
                        ?: SearchGameResultFragment()
                detailListFragment.setParams(mSearchKey ?: "", mSearchType.value)
                transaction.replace(R.id.search_result, detailListFragment, SearchGameResultFragment::class.java.name)
            }
            else -> {
                //do nothing
            }
        }
        mDisplayType = type
        transaction.commitAllowingStateLoss()
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEvent(search: EBSearch) {
        when (search.type) {
            SearchType.HISTORY.value -> search(SearchType.HISTORY, search.key)
            SearchType.HOT.value -> search(SearchType.HOT, search.key)

            "click" -> DataCollectionUtils.uploadSearchClick(
                this, mSearchKey, mSearchType.value, "搜索页面",
                search.gameId, search.gameName
            )
            "search" -> {
                DataCollectionUtils.uploadSearch(
                    this, mSearchKey, mSearchType.value, "搜索页面",
                    search.gameId, search.gameName
                )
            }
        }
    }

    override fun handleBackPressed(): Boolean {
        val fragment = supportFragmentManager.findFragmentByTag(SearchDefaultFragment::class.java.name)
        if (fragment == null) {
            updateDisplayType(DEFAULT)
            return true
        }
        return super.handleBackPressed()
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        updateStatusBarColor(R.color.background_white, R.color.background_white)
    }

    override fun isAutoResetViewBackgroundEnabled() = true

    companion object {
        const val KEY_SEARCH_TYPE = "search_type"
        private const val KEY_DISPLAY_TYPE = "display_type"
        private const val KEY_SEARCH_IMMEDIATELY = "search_immediately"
        private const val HINT_TEXT = "搜索游戏..."

        @JvmStatic
        fun getIntent(
            context: Context,
            searchImmediately: Boolean,
            hint: String,
            entrance: String,
            sourceEntrance: String
        ): Intent {
            val intent = Intent(context, SearchActivity::class.java)
            intent.putExtra(KEY_SEARCH_IMMEDIATELY, searchImmediately)
            intent.putExtra(EntranceConsts.KEY_HINT, hint)
            intent.putExtra(EntranceConsts.KEY_ENTRANCE, entrance)
            intent.putExtra(EntranceConsts.KEY_SOURCE_ENTRANCE, sourceEntrance)
            return intent
        }
    }
}

enum class SearchType(var value: String) {
    AUTO("auto"),
    DEFAULT("default"),
    HISTORY("history"),
    MANUAL("initiative"),
    HOT("remen");

    fun toChinese() = when (this) {
        AUTO -> "自动搜索"
        DEFAULT -> "默认搜索"
        HISTORY -> "历史搜索"
        MANUAL -> "主动搜索"
        HOT -> "热门搜索"
    }

    companion object {
        @JvmStatic
        fun fromString(typeString: String) = values().find { typeString == it.value } ?: DEFAULT
    }
}

/**
 *
 * [DEFAULT] 默认搜索页
 * [GAME_DIGEST] 游戏为部分文字样式的列表
 * [GAME_DETAIL] 游戏全为标准样式的列表
 * [FORUM_OR_USER] 论坛内容和用户
 */
enum class DisplayType(var value: Int) {
    DEFAULT(0),
    GAME_DIGEST(1),
    GAME_DETAIL(2),
    FORUM_OR_USER(3);
}
