package com.gh.gamecenter.gamecollection.publish

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.*
import android.widget.PopupWindow
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.updateLayoutParams
import androidx.core.widget.doOnTextChanged
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.ErrorHelper
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.CropImageActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.mvvm.Status
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.core.utils.ClickUtils
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.PatternUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.*
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.gamecollection.choose.AddGamesDialogFragment
import com.gh.gamecenter.gamecollection.choose.ChooseGamesAdapter
import com.gh.gamecenter.gamecollection.choose.ChooseGamesViewModel
import com.gh.gamecenter.gamecollection.tag.GameCollectionTagSelectActivity
import com.gh.gamecenter.gamecollection.tag.GameCollectionTagSelectFragment
import com.zhihu.matisse.Matisse
import com.zhihu.matisse.internal.utils.PathUtils
import org.greenrobot.eventbus.EventBus
import org.json.JSONObject
import java.lang.ref.WeakReference
import java.util.*

/**
 * 创建/编辑游戏单
 */
class GameCollectionEditActivity : ToolBarActivity(), ChooseGamesAdapter.ItemDragListener {

    private lateinit var mMenuPost: MenuItem
    private lateinit var mBinding: ActivityGameCollectionEditBinding
    private lateinit var mViewModel: GameCollectionEditViewModel
    private lateinit var mChooseGamesViewModel: ChooseGamesViewModel
    private lateinit var mAdapter: ChooseGamesAdapter
    private lateinit var mLayoutManager: LinearLayoutManager
    private var mProcessingDialog: WaitingDialogFragment? = null
    private var mPatchCommitCount = 0
    private var mActivityId = ""
    private var mActivityName = ""
    private var mGameEntity: GameEntity? = null
    private var mIsCreateGameCollection = false
    private var mPath = ""
    private val mItemTouchCallback = CustomItemTouchHelper(this)
    private val mItemTouchHelper = ItemTouchHelper(mItemTouchCallback)
    private var mPopupWindow: PopupWindow? = null
    private var mIsCollapsed = false

    override fun getLayoutId(): Int = R.layout.activity_game_collection_edit

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        updateStatusBarColor(com.gh.gamecenter.common.R.color.ui_surface, com.gh.gamecenter.common.R.color.ui_surface)
        mBinding = ActivityGameCollectionEditBinding.bind(mContentView)
        mViewModel = viewModelProvider()
        mChooseGamesViewModel = viewModelProvider(ChooseGamesViewModel.Factory())
        setToolbarMenu(R.menu.menu_game_collection_edit)
        mMenuPost = getMenuItem(R.id.menu_game_collection_post)
        setNavigationTitle("创建游戏单")
        mViewModel.gameCollectionPatch = intent.getParcelableExtra(GamesCollectionEntity::class.java.name)
        mIsCreateGameCollection = intent.getBooleanExtra(EntranceConsts.KEY_CREATE_GAME_COLLECTION, false)
        mPath = intent.getStringExtra(EntranceConsts.KEY_PATH) ?: ""
        if (mPath.isNotEmpty()) {
            if (mIsCreateGameCollection) {
                SensorsBridge.trackEvent("GameCollectCreateClick", "source_entrance", mPath)
                NewLogUtils.logEnterGameCollectionCreate(mPath)
            } else if (mViewModel.gameCollectionPatch != null) {
                SensorsBridge.trackEvent("GameCollectEditClick", json {
                    "source_entrance" to mPath
                    "is_self_only" to (mViewModel.gameCollectionPatch?.display == "self_only")
                    "game_collect_title" to mViewModel.gameCollectionPatch?.title
                    "game_collect_id" to mViewModel.gameCollectionPatch?.id
                })
            }
        }
        mActivityId = intent.getStringExtra(EntranceConsts.KEY_ACTIVITY_ID) ?: ""
        mActivityName = intent.getStringExtra(EntranceConsts.KEY_ACTIVITY_NAME) ?: ""
        if (mActivityId.isNotEmpty() && mActivityName.isNotEmpty()) {
            mViewModel.selectActivityTag = ActivityLabelEntity(id = mActivityId, name = mActivityName)
            mBinding.activityTipTv.text = mActivityName
        }
        val gameId = intent.getStringExtra(EntranceConsts.KEY_GAMEID) ?: ""
        if (gameId.isNotEmpty()) {
            mViewModel.getGameDigest(gameId) {
                if (it != null) {
                    var isDuplicate = false
                    val gamesList = ArrayList<GameEntity>()
                    val simpleGames = mViewModel.gameCollectionPatch?.games?.map { game -> game.toGameEntity() }
                    if (!simpleGames.isNullOrEmpty()) {
                        simpleGames.forEach { game ->
                            if (game.id == gameId) isDuplicate = true
                        }
                        gamesList.addAll(simpleGames)
                    }
                    mGameEntity = it
                    mChooseGamesViewModel.chooseGamesLiveData.postValue(gamesList.apply { if (!isDuplicate) add(it) })
                }
            }
        }

        mBinding.collapsingToolbar.scrimShownAction = {
            mIsCollapsed = it
            if (it && SPUtils.getBoolean(Constants.SP_SHOW_GAME_COLLECTION_DOUBLE_TAP_TOAST, true)) {
                toast("双击标题栏返回页面顶部")
                SPUtils.setBoolean(Constants.SP_SHOW_GAME_COLLECTION_DOUBLE_TAP_TOAST, false)
            }
        }
        mBinding.gamesRv.run {
            mLayoutManager = LinearLayoutManager(this@GameCollectionEditActivity)
            layoutManager = mLayoutManager
            adapter = ChooseGamesAdapter(this@GameCollectionEditActivity, this@GameCollectionEditActivity).apply {
                mAdapter = this
            }
            mItemTouchHelper.attachToRecyclerView(this)
        }

        initData()
        observeData()
        initListener()

        if (SPUtils.getBoolean(Constants.SP_SHOW_GAME_COLLECTION_EDIT_GUIDE, true)) {
            mPopupWindow = showInfoGuidePopupWindow()
        }

        if (intent.getBooleanExtra(EntranceConsts.KEY_SHOW_ADD_GAMES_DIALOG, false)
            || mViewModel.gameCollectionPatch == null
        ) {
            mBaseHandler.postDelayed({
                AddGamesDialogFragment.show(this)
            }, 500)
        }

    }

    @SuppressLint("ClickableViewAccessibility")
    private fun initListener() {
        mBinding.gameCollectionTitleEt.run {
            doOnTextChanged { text, start, _, _ ->
                if (text?.contains("\n") == true) {
                    setText(text.toString().replace("\n", ""))
                    setSelection(start)
                    return@doOnTextChanged
                }
                if (PatternUtils.isHasSpace(text.toString())) {
                    setText(PatternUtils.replaceSpace(text.toString()))
                    setSelection(start)
                    return@doOnTextChanged
                }
            }
        }
        mBinding.gameCollectionIntroduceEt.run {
            setOnTouchListener { v, event ->
                if (v.canScrollVertically(1) || v.canScrollVertically(-1)) {
                    v.parent.requestDisallowInterceptTouchEvent(true)
                    if (event.action == MotionEvent.ACTION_UP) {
                        v.parent.requestDisallowInterceptTouchEvent(false)
                    }
                }
                false
            }
            doOnTextChanged { text, start, _, _ ->
                if (PatternUtils.isHasWrap(text.toString())) {
                    setText(PatternUtils.replaceWrap(text.toString()))
                    setSelection(start)
                    return@doOnTextChanged
                }
                if (PatternUtils.isHasSpace(text.toString())) {
                    setText(PatternUtils.replaceSpace(text.toString()))
                    setSelection(start)
                    return@doOnTextChanged
                }
            }
        }
        mBinding.uploadPictureBtn.setOnClickListener {
//            PermissionHelper.checkStoragePermissionBeforeAction(
//                this,
//                object : EmptyCallback {
//                    override fun onCallback() {
//                        startActivityForResult(
//                            LocalMediaActivity.getIntent(
//                                this@GameCollectionEditActivity,
//                                LocalMediaActivity.ChooseType.IMAGE,
//                                1,
//                                "创建游戏单"
//                            ), REQUEST_CODE_IMAGE
//                        )
//                    }
//                })
            ChooseGameCollectionCoverTypeDialog.show(this, this::class.java.name)
        }

        mBinding.changePosterBtn.setOnClickListener { mBinding.uploadPictureBtn.performClick() }

        mBinding.deleteBtn.setOnClickListener {
            mViewModel.imageUrl = ""
            mViewModel.imagePath = ""
            mBinding.uploadPictureTv.text = "点击上传图片"
            initPosterUI()
        }

        mBinding.gameCollectionIntroduceEt.doOnTextChanged { text, _, _, _ ->
            mBinding.introduceSizeTv.text = "${text?.toString()?.lengthOfEmojiHalf() ?: 0}/200"
        }

        mBinding.chooseLabelContainer.setOnClickListener {
            startActivityForResult(
                GameCollectionTagSelectActivity.getIntent(this, 3, mViewModel.tags),
                REQUEST_CHOOSE_TAG
            )
        }

        mBinding.addGamesButton.setOnClickListener {
            scrollToAddGames()
            AddGamesDialogFragment.show(this)
        }

        mBinding.addGamesTv.setOnClickListener { mBinding.addGamesButton.performClick() }
        mBinding.chooseActivityContainer.setOnClickListener {
            if (mViewModel.gameCollectionPatch?.status != "draft" && mViewModel.gameCollectionPatch?.isLocalDraft == false) return@setOnClickListener
            ChooseGameCollectionActivityDialog.show(this, mViewModel.selectActivityTag?.id, this::class.java.name)
        }
        mBinding.normsLinkTv.setOnClickListener {
            startActivity(WebActivity.getWebIntent(this, "游戏单管理规范", Constants.GAME_COLLECTION_RULE))
        }
        mTitleTv?.setOnClickListener {
            if (ClickUtils.isFastDoubleClick(it.id, 300)) {
                scrollToTop()
            }
        }
    }

    private fun initData(isFirst: Boolean = true) {
        mBinding.gameCollectionTitleEt.filters = arrayOf(TextHelper.getFilterOfEmojiHalf(20, "最多输入20个字"))
        mBinding.gameCollectionIntroduceEt.filters = arrayOf(TextHelper.getFilterOfEmojiHalf(200, "最多输入200个字"))
        initTagsUI(mViewModel.tags)

        mViewModel.gameCollectionPatch?.run {
            if (!activityTags.isNullOrEmpty() && mActivityId.isEmpty() && mActivityName.isEmpty()) {
                mViewModel.selectActivityTag = activityTags!![0]
                mBinding.activityTipTv.text = activityTags!![0].name
            }
            mViewModel.imageUrl = cover
            if (status != "draft" && !isLocalDraft) {
                setNavigationTitle("编辑游戏单")
            }
            initPosterUI()
            mBinding.gameCollectionTitleEt.setText(title)
            mBinding.gameCollectionTitleEt.setSelection(title.length)
            mBinding.gameCollectionIntroduceEt.setText(intro)
            mBinding.gameCollectionIntroduceEt.setSelection(intro.length)
            mBinding.selfOnlyCb.isChecked = display == "self_only"
            if (isFirst) {
                mViewModel.getGameCollectionDetail(id)
            }
        } ?: mViewModel.getDraft()
    }

    private fun observeData() {
        mChooseGamesViewModel.chooseGamesLiveData.observe(this) {
            mBinding.gameCountTv.text = "已收录${it.size}款游戏"
            mBinding.addGamesTv.goneIf(it.isNotEmpty())
            mBinding.addGamesButton.goneIf(it.isEmpty())
            mAdapter.setListData(it)
        }
        mViewModel.processDialog.observe(this) {
            if (it.isShow) {
                if (mProcessingDialog?.dialog?.isShowing == true) {
                    mProcessingDialog?.uploadWaitingHint(it.msg)
                } else {
                    mProcessingDialog = WaitingDialogFragment.newInstance(it.msg, false)
                    mProcessingDialog?.show(supportFragmentManager, null)
                }
            } else {
                mProcessingDialog?.dismiss()
            }
        }
        mViewModel.uploadImageSuccessLiveData.observe(this) {
            if (it.isNotEmpty()) {
                initPosterUI()
            }
            mBinding.uploadPictureTv.text = "点击上传图片"
        }
        mViewModel.postLiveData.observe(this) {
            if (it.status == Status.SUCCESS) {
                toast("提交成功")
                EventBus.getDefault().post(EBReuse("createGameCollectionSuccess"))
                it.data?.run {
                    val games = mChooseGamesViewModel.chooseGamesLiveData.value ?: arrayListOf()
                    if (mIsCreateGameCollection) {
                        SensorsBridge.trackEvent("GameCollectCreateSuccess", json {
                            "game_collect_status" to if (mBinding.selfOnlyCb.isChecked) "仅自己可见" else "公开"
                            "game_num" to games.size
                            "game_collect_title" to mBinding.gameCollectionTitleEt.text.toString().trim()
                            "game_collect_id" to it.data as String
                        })
                    } else if (mViewModel.gameCollectionPatch != null) {
                        SensorsBridge.trackEvent("GameCollectEditSuccess", json {
                            "game_collect_status" to if (mBinding.selfOnlyCb.isChecked) "仅自己可见" else "公开"
                            "game_num" to games.size
                            "game_collect_title" to mBinding.gameCollectionTitleEt.text.toString().trim()
                            "game_collect_id" to mViewModel.gameCollectionPatch?.id
                        })
                    }

                    if (mActivityName.isNotEmpty()) {
                        NewLogUtils.logCreateGameCollectionSuccess(
                            games.map { gameEntity -> gameEntity.id }.toList(),
                            mBinding.gameCollectionTitleEt.text.toString().trim(),
                            this,
                            mActivityName
                        )
                    }
                    if (mGameEntity != null || mActivityName.isNotEmpty()) {
                        com.gh.common.util.NewFlatLogUtils.logActivityGameListCreateSuccessV2(
                            if (mGameEntity != null) "添加" else "立即投稿",
                            if (mGameEntity != null) mGameEntity?.id ?: "" else "",
                            if (mGameEntity != null) mGameEntity?.name ?: "" else "",
                            it.data ?: "",
                            mBinding.gameCollectionTitleEt.text.toString().trim(),
                            mActivityId,
                            mActivityName
                        )
                    }
                }
                finish()
            } else {
                val errorMsg = it.exception?.response()?.errorBody()?.string() ?: ""
                val errorCode = JSONObject(errorMsg).getInt("code")
                if (errorCode == 400401) {
                    CheckLoginUtils.checkLogin(this, mEntrance) {}
                    return@observe
                }
                ErrorHelper.handleError(this, errorMsg, false, "发布游戏单", "社区实名") {
                    if (::mMenuPost.isInitialized) {
                        onMenuItemClick(mMenuPost)
                    }
                }
            }
        }
        mViewModel.detailLiveData.observe(this) {
            mViewModel.gameCollectionPatch?.apply {
                games = it.games
                tags = it.tags
                title = it.title
                intro = it.intro
                cover = it.cover
                display = it.display
            }
            mViewModel.gameCollectionPatch?.run {
                initData(false)
                mViewModel.tags = tags ?: arrayListOf()
                initTagsUI(mViewModel.tags)
                val simpleGames = games?.map { game -> game.toGameEntity() }?.toList()
                mChooseGamesViewModel.chooseGamesLiveData.postValue(ArrayList(simpleGames))
            }
        }
        mViewModel.draftLiveData.observe(this) {
            mViewModel.gameCollectionPatch = it.convertGameCollectionEntity()
            mViewModel.gameCollectionPatch?.run {
                isLocalDraft = true
                initData(false)
                mViewModel.tags = tags ?: arrayListOf()
                initTagsUI(mViewModel.tags)
                val simpleGames = games?.map { game -> game.toGameEntity() }
                var isDuplicate = false
                if (!simpleGames.isNullOrEmpty()) {
                    simpleGames.forEach { game ->
                        if (mGameEntity != null && game.id == mGameEntity?.id) isDuplicate = true
                    }
                }
                mChooseGamesViewModel.chooseGamesLiveData.postValue(ArrayList(simpleGames).apply {
                    if (mGameEntity != null && !isDuplicate) add(mGameEntity)
                })
            }
            if (!it.activityTags.isNullOrEmpty() && mActivityId.isEmpty() && mActivityName.isEmpty()) {
                mViewModel.selectActivityTag = it.activityTags!![0]
                mBinding.activityTipTv.text = it.activityTags!![0].name
            }
        }
    }

    private fun scrollToTop() {
        val firstItemPosition = mLayoutManager.findFirstVisibleItemPosition()
        if (firstItemPosition >= 10) {
            mBinding.gamesRv.scrollToPosition(6)
        }
        mBinding.gamesRv.smoothScrollToPosition(0)
        mBinding.appbar.setExpanded(true)
    }

    private fun scrollToAddGames() {
        mBinding.gamesRv.smoothScrollToPosition(0)
        mBinding.appbar.setExpanded(false)
    }

    override fun onMenuItemClick(item: MenuItem?): Boolean {
        item?.run {
            if (itemId == R.id.menu_game_collection_post) {
                debounceActionWithInterval(R.id.menu_game_collection_post, 3000L) {
                    verifyData()
                }
            }
        }
        return super.onMenuItemClick(item)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (data == null || resultCode != Activity.RESULT_OK) return
        when (requestCode) {
            REQUEST_CHOOSE_TAG -> {
                val tags = data.getParcelableArrayListExtra<TagInfoEntity>(GameCollectionTagSelectFragment.SELECTED_TAG)
                    ?: arrayListOf()
                mViewModel.tags = tags
                initTagsUI(tags)
            }
        }
    }

    fun onActivityDialogResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (resultCode == Activity.RESULT_OK && data != null) {
            if (requestCode == REQUEST_CODE_IMAGE) {
                val imagePath = data.getStringExtra(CropImageActivity.RESULT_CLIP_PATH) ?: ""
                mViewModel.imageUrl = ""
                mViewModel.imagePath = imagePath
                if (imagePath.isEmpty()) {
                    mBinding.uploadPictureTv.text = "点击上传图片"
                } else {
                    mBinding.uploadPictureTv.text = "图片上传中..."
                    mViewModel.uploadPoster()
                }
                initPosterUI()
            } else if (requestCode == ChooseGameCollectionDefaultCoverDialog.REQUEST_CODE_DEFAULT_IMAGE) {
                val entity = data.getParcelableExtra<GameCollectionCoverEntity>(EntranceConsts.KEY_DATA)
                if (entity != null) {
                    mViewModel.imageUrl = entity.url
                    mViewModel.uploadImageSuccessLiveData.postValue(entity.url)
                }
            } else if (requestCode == REQUEST_CHOOSE_ACTIVITY) {
                val entity = data.getParcelableExtra<ActivityLabelEntity>(EntranceConsts.KEY_DATA)
                if (entity != null) {
                    mViewModel.selectActivityTag = entity
                    mBinding.activityTipTv.text = entity.name
                } else {
                    mViewModel.selectActivityTag = null
                    mBinding.activityTipTv.text = ""
                }
            }
        }
    }

    private fun initPosterUI() {
        mBinding.placeholderView.goneIf(mViewModel.imageUrl.isNotEmpty())
        mBinding.uploadPictureBtn.goneIf(mViewModel.imageUrl.isNotEmpty())
        mBinding.posterView.goneIf(mViewModel.imageUrl.isEmpty())
        mBinding.changePosterBtn.goneIf(mViewModel.imageUrl.isEmpty())
        mBinding.deleteBtn.goneIf(mViewModel.imageUrl.isEmpty())
        if (mViewModel.imageUrl.isNotEmpty()) {
            ImageUtils.display(mBinding.posterView, mViewModel.imageUrl)
        }
    }

    private fun initTagsUI(tags: ArrayList<TagInfoEntity>) {
        mBinding.gameCollectionTagsContainer.removeAllViews()
        if (tags.isEmpty()) {
            val tagBinding = ItemGameCollectionFlexTagBinding.inflate(LayoutInflater.from(this), null, false)
            tagBinding.tagNameTv.run {
                text = "请至少添加一个标签"
                setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(this@GameCollectionEditActivity))
                textSize = 12F
            }
            tagBinding.divider.visibility = View.GONE
            mBinding.gameCollectionTagsContainer.addView(tagBinding.root)
        } else {
            tags.forEachIndexed { index, tag ->
                val tagBinding = ItemGameCollectionEditFlexTagBinding.inflate(LayoutInflater.from(this), null, false)
                tagBinding.tagNameTv.text = tag.name
                tagBinding.divider.goneIf(index == tags.size - 1)
                mBinding.gameCollectionTagsContainer.addView(tagBinding.root)
            }
        }
    }

    override fun handleBackPressed(): Boolean {
        if (mPopupWindow?.isShowing == true) {
            mPopupWindow?.dismiss()
            return true
        }

        val patch = mViewModel.gameCollectionPatch
        if (patch != null && patch.status != "draft" && !patch.isLocalDraft) {
            SensorsBridge.trackEvent("GameCollectExitEditDialogShow", json {
                "is_self_only" to mBinding.selfOnlyCb.isChecked
                "game_collect_title" to patch.title
                "game_collect_id" to patch.id
            })
            DialogHelper.showDialog(
                this,
                "温馨提示",
                "退出将不会保留本次游戏单编辑的内容，是否确定退出",
                "确定",
                "取消",
                {
                    SensorsBridge.trackEvent("GameCollectExitEditDialogClick", json {
                        "is_self_only" to mBinding.selfOnlyCb.isChecked
                        "button_name" to "确定"
                        "game_collect_title" to patch.title
                        "game_collect_id" to patch.id
                    })
                    finish()
                },
                {
                    SensorsBridge.trackEvent("GameCollectExitEditDialogClick", json {
                        "is_self_only" to mBinding.selfOnlyCb.isChecked
                        "button_name" to "取消"
                        "game_collect_title" to patch.title
                        "game_collect_id" to patch.id
                    })
                },
                {
                    SensorsBridge.trackEvent("GameCollectExitEditDialogClick", json {
                        "is_self_only" to mBinding.selfOnlyCb.isChecked
                        "button_name" to "关闭弹窗"
                        "game_collect_title" to patch.title
                        "game_collect_id" to patch.id
                    })
                },
                extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
            )
            return true
        } else if (patch == null || patch.isLocalDraft) {
            val games = mChooseGamesViewModel.chooseGamesLiveData.value ?: arrayListOf()
            val title = mBinding.gameCollectionTitleEt.text.toString()
            val introduce = mBinding.gameCollectionIntroduceEt.text.toString()
            if (mViewModel.imageUrl.isNotEmpty()
                || mViewModel.tags.isNotEmpty()
                || games.isNotEmpty()
                || title.isNotEmpty()
                || introduce.isNotEmpty()
                || mViewModel.selectActivityTag != null
            ) {
                val entity = GameCollectionDraft()
                entity.tags = mViewModel.tags
                if (mViewModel.selectActivityTag != null) entity.activityTags =
                    arrayListOf(mViewModel.selectActivityTag!!)
                entity.title = title
                entity.intro = introduce
                entity.cover = mViewModel.imageUrl
                entity.display = if (mBinding.selfOnlyCb.isChecked) "self_only" else ""
                entity.games = arrayListOf()
                entity.games?.addAll(games.map { it.toSimpleGame() }.toList())
                mViewModel.addDraft(entity)
            }
        }
        return super.handleBackPressed()
    }

    private fun verifyData() {
        val games = mChooseGamesViewModel.chooseGamesLiveData.value ?: arrayListOf()
        val title = mBinding.gameCollectionTitleEt.text.toString().trim()

        if (mIsCreateGameCollection) {
            SensorsBridge.trackEvent("GameCollectCreateSubmit", json {
                "is_self_only" to mBinding.selfOnlyCb.isChecked
                "game_num" to games.size
            })
        } else if (mViewModel.gameCollectionPatch != null) {
            SensorsBridge.trackEvent("GameCollectEditSubmit", json {
                "is_self_only" to mBinding.selfOnlyCb.isChecked
                "game_num" to games.size
                "game_collect_title" to mViewModel.gameCollectionPatch?.title
                "game_collect_id" to mViewModel.gameCollectionPatch?.id
            })
        }

        if (mViewModel.imageUrl.isEmpty()) {
            toast("请上传游戏单的封面")
            return
        }
        if (mViewModel.tags.isEmpty()) {
            toast("请选择游戏单的标签")
            return
        }

        if (title.isEmpty()) {
            toast("请填写游戏单的标题")
            return
        }
        val introduce = mBinding.gameCollectionIntroduceEt.text.toString().trim()
        val isSelfOnly = mBinding.selfOnlyCb.isChecked
        val requestMap = hashMapOf(
            "id" to (mViewModel.gameCollectionPatch?.id ?: ""),
            "title" to title,
            "intro" to introduce,
            "tag_ids" to mViewModel.tags.map { it.id }.toList(),
            "cover" to mViewModel.imageUrl,
            "display" to if (isSelfOnly) "self_only" else "",
            "games" to games.map {
                hashMapOf<String, Any>(
                    "_id" to it.id,
                    "recommend_star" to it.recommendStar,
                    "recommend_text" to it.recommendText,
                )
            }.toList()
        )
        if (mViewModel.selectActivityTag != null) {
            requestMap["activity_tag_ids"] = listOf(mViewModel.selectActivityTag?.id)
        }

        val patch = mViewModel.gameCollectionPatch
        if (patch != null
            && !patch.isLocalDraft
            && !mBinding.selfOnlyCb.isChecked
            && games.size < 8
        ) {
            if (mPatchCommitCount < 2) {
                toast("游戏单收录的游戏不能少于8款")
                scrollToAddGames()
                mPatchCommitCount++
            } else {
                toast("没想好收录的游戏，开启仅自己可见试试")
                mPatchCommitCount++
            }
            return
        }

        if (isSelfOnly) {
            SensorsBridge.trackEvent("GameCollectSelfOnlyDialogShow", json {
                "source_entrance" to mPath
                "game_num" to games.size
                "game_collect_title" to mViewModel.gameCollectionPatch?.title
                "game_collect_id" to mViewModel.gameCollectionPatch?.id
            })
            DialogHelper.showDialog(
                this,
                "温馨提示",
                "游戏单开启“仅自己可见”后，将不会对其他用户展示，是否继续提交",
                "确定",
                "取消",
                {
                    SensorsBridge.trackEvent("GameCollectSelfOnlyDialogClick", json {
                        "source_entrance" to mPath
                        "button_name" to "确定"
                        "game_num" to games.size
                        "game_collect_title" to mViewModel.gameCollectionPatch?.title
                        "game_collect_id" to mViewModel.gameCollectionPatch?.id
                    })
                    mViewModel.uploadContent(this, requestMap)
                },
                {
                    SensorsBridge.trackEvent("GameCollectSelfOnlyDialogClick", json {
                        "source_entrance" to mPath
                        "button_name" to "取消"
                        "game_num" to games.size
                        "game_collect_title" to mViewModel.gameCollectionPatch?.title
                        "game_collect_id" to mViewModel.gameCollectionPatch?.id
                    })
                },
                {
                    SensorsBridge.trackEvent("GameCollectSelfOnlyDialogClick", json {
                        "source_entrance" to mPath
                        "button_name" to "关闭弹窗"
                        "game_num" to games.size
                        "game_collect_title" to mViewModel.gameCollectionPatch?.title
                        "game_collect_id" to mViewModel.gameCollectionPatch?.id
                    })
                },
                extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
            )
        } else {
            if (games.size < 8) {
                SensorsBridge.trackEvent("GameCollectSaveDraftDialogShow")
                DialogHelper.showDialog(
                    this,
                    "温馨提示",
                    "游戏单需要收录至少8个游戏，才可以投稿至游戏单广场，是否在“我的光环-我的游戏单”继续保存为草稿",
                    "继续保存",
                    "添加游戏",
                    {
                        SensorsBridge.trackEvent("GameCollectSaveDraftDialogClick", "button_name", "继续保存")
                        mViewModel.uploadContent(this, requestMap)
                    },
                    {
                        SensorsBridge.trackEvent("GameCollectSaveDraftDialogClick", "button_name", "添加游戏")
                        AddGamesDialogFragment.show(this)
                    },
                    {
                        SensorsBridge.trackEvent("GameCollectSaveDraftDialogClick", "button_name", "关闭弹窗")
                    },
                    extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
                )
            } else {
                DialogHelper.showDialog(
                    this,
                    "温馨提示",
                    "游戏单会在1-2个工作日内审核完成，您可以在“我的光环-我的游戏单”查看进度",
                    "继续提交",
                    "取消",
                    {
                        mViewModel.uploadContent(this, requestMap)
                    },
                    extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
                )
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        mChooseGamesViewModel.chooseGamesLiveData.postValue(arrayListOf())
        if (mIsCreateGameCollection) {
            SensorsBridge.trackEvent("GameCollectCreateCancel")
        }
    }

    class CustomItemTouchHelper(val activity: GameCollectionEditActivity) : ItemTouchHelper.Callback() {

        var activityReference: WeakReference<GameCollectionEditActivity> = WeakReference(activity)

        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 activity = activityReference.get()
            activity?.run {
                val oldPosition = viewHolder.bindingAdapterPosition
                val targetPosition = target.bindingAdapterPosition
                if (targetPosition > oldPosition && !mIsCollapsed) {
                    scrollToAddGames()
                }

                mAdapter.notifyItemMoved(oldPosition, targetPosition)
                Collections.swap(mAdapter.entityList, oldPosition, targetPosition)
                val games = mChooseGamesViewModel.chooseGamesLiveData.value ?: arrayListOf()
                Collections.swap(games, oldPosition, targetPosition)
            }
            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()
        updateStatusBarColor(com.gh.gamecenter.common.R.color.ui_surface, com.gh.gamecenter.common.R.color.ui_surface)
        mMenuPost.actionView?.findViewById<TextView>(R.id.postTv)?.background =
            R.drawable.textview_concern_red_up_round.toDrawable(this)
        if (::mBinding.isInitialized) {
            mBinding.run {
                root.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(this@GameCollectionEditActivity))
                labelDivider.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_divider.toColor(this@GameCollectionEditActivity))
                activityDivider.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_divider.toColor(this@GameCollectionEditActivity))
                titleDivider.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_divider.toColor(this@GameCollectionEditActivity))
                introduceDivider.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_divider.toColor(this@GameCollectionEditActivity))
                placeholderView.background =
                    com.gh.gamecenter.common.R.drawable.bg_shape_f5_radius_8.toDrawable(this@GameCollectionEditActivity)
                selfOnlyCb.background =
                    R.drawable.border_round_stroke_0dot5_eee_999.toDrawable(this@GameCollectionEditActivity)
                uploadPictureTv.setTextColor(com.gh.gamecenter.common.R.color.text_instance.toColor(this@GameCollectionEditActivity))
                activityTv.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this@GameCollectionEditActivity))
                gameCollectionTitleEt.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this@GameCollectionEditActivity))
                gameCollectionIntroduceEt.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(this@GameCollectionEditActivity))
                introduceSizeTv.setTextColor(com.gh.gamecenter.common.R.color.text_instance.toColor(this@GameCollectionEditActivity))
                normsLinkTv.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(this@GameCollectionEditActivity))
                selfOnlyCb.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(this@GameCollectionEditActivity))
                activityTipTv.setHintTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(this@GameCollectionEditActivity))
                gameCollectionTitleEt.setHintTextColor(com.gh.gamecenter.common.R.color.text_instance.toColor(this@GameCollectionEditActivity))
                gameCollectionIntroduceEt.setHintTextColor(com.gh.gamecenter.common.R.color.text_instance.toColor(this@GameCollectionEditActivity))
                for (i in 0 until mBinding.gameCollectionTagsContainer.childCount) {
                    mBinding.gameCollectionTagsContainer.getChildAt(i)?.findViewById<TextView>(R.id.tagNameTv)
                        ?.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(this@GameCollectionEditActivity))
                }
            }
            mAdapter.notifyItemRangeChanged(0, mAdapter.itemCount)
        }
    }


    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 = mChooseGamesViewModel.chooseGamesLiveData.value ?: arrayListOf()
            Collections.swap(games, i, i - 1)
        }
        mAdapter.notifyDataSetChanged()
        mBinding.gamesRv.scrollToPosition(0)
    }

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

    private fun showInfoGuidePopupWindow(): PopupWindow {
        val guideBinding = LayoutGameCollectionInfoGuideBinding.inflate(layoutInflater)
        val popupWindow = BugFixedPopupWindow(
            guideBinding.root,
            ConstraintLayout.LayoutParams.MATCH_PARENT,
            ConstraintLayout.LayoutParams.MATCH_PARENT
        )
        guideBinding.infoIv.updateLayoutParams<ConstraintLayout.LayoutParams> {
            setMargins(0, DisplayUtils.getStatusBarHeight(resources) + 48F.dip2px(), 0, 0)
        }
        guideBinding.guideContainer.setOnClickListener {
            popupWindow.dismiss()
        }
        return popupWindow.apply {
            isTouchable = true
            isFocusable = true
            isOutsideTouchable = true
            isClippingEnabled = false
            animationStyle = com.gh.gamecenter.common.R.style.popup_window_ease_in_and_out_anim_style
            setOnDismissListener {
                if (SPUtils.getBoolean(Constants.SP_SHOW_GAME_COLLECTION_EDIT_GUIDE, true)) {
                    mPopupWindow = showSubmitGuidePopupWindow()
                }
            }
            window.decorView.postDelayed({
                if (!isFinishing) {
                    showAtLocation(window.decorView, Gravity.TOP, 0, 0)
                }
            }, 100)
        }
    }

    private fun showSubmitGuidePopupWindow(): PopupWindow {
        val guideBinding = LayoutGameCollectionSubmitGuideBinding.inflate(layoutInflater)
        val popupWindow = BugFixedPopupWindow(
            guideBinding.root,
            ConstraintLayout.LayoutParams.MATCH_PARENT,
            ConstraintLayout.LayoutParams.MATCH_PARENT
        )
        guideBinding.submitIv.updateLayoutParams<ConstraintLayout.LayoutParams> {
            setMargins(0, DisplayUtils.getStatusBarHeight(resources), 8F.dip2px(), 0)
        }
        guideBinding.guideContainer.setOnClickListener {
            popupWindow.dismiss()
        }
        return popupWindow.apply {
            isTouchable = true
            isFocusable = true
            isOutsideTouchable = true
            isClippingEnabled = false
            animationStyle = com.gh.gamecenter.common.R.style.popup_window_ease_in_and_out_anim_style
            setOnDismissListener {
                SPUtils.setBoolean(Constants.SP_SHOW_GAME_COLLECTION_EDIT_GUIDE, false)
                mPopupWindow = null
            }
            if (!isFinishing) {
                showAtLocation(window.decorView, Gravity.TOP, 0, 0)
            }
        }
    }

    companion object {

        const val REQUEST_CODE_IMAGE = 100
        const val REQUEST_CHOOSE_GAMES = 102
        const val REQUEST_CHOOSE_TAG = 103
        const val REQUEST_CHOOSE_ACTIVITY = 105

        @JvmStatic
        fun getCreateIntent(context: Context, entrance: String = "", path: String = ""): Intent {
            val intent = Intent(context, GameCollectionEditActivity::class.java)
            intent.putExtra(EntranceConsts.KEY_CREATE_GAME_COLLECTION, true)
            intent.putExtra(EntranceConsts.KEY_ENTRANCE, mergeEntranceAndPath(entrance, path))
            intent.putExtra(EntranceConsts.KEY_PATH, path)
            return intent
        }

        @JvmStatic
        fun getIntent(
            context: Context,
            entity: GamesCollectionEntity,
            entrance: String = "",
            path: String = "",
            showAddGamesDialog: Boolean = false
        ): Intent {
            val intent = Intent(context, GameCollectionEditActivity::class.java)
            intent.putExtra(GamesCollectionEntity::class.java.name, entity)
            intent.putExtra(EntranceConsts.KEY_ENTRANCE, mergeEntranceAndPath(entrance, path))
            intent.putExtra(EntranceConsts.KEY_PATH, path)
            intent.putExtra(EntranceConsts.KEY_SHOW_ADD_GAMES_DIALOG, showAddGamesDialog)
            return intent
        }

        @JvmStatic
        fun getCreateIntent(
            context: Context,
            activityId: String = "",
            activityName: String = "",
            gameId: String = "",
            entrance: String = "",
            path: String = ""
        ): Intent {
            val intent = Intent(context, GameCollectionEditActivity::class.java)
            intent.putExtra(EntranceConsts.KEY_ACTIVITY_ID, activityId)
            intent.putExtra(EntranceConsts.KEY_ACTIVITY_NAME, activityName)
            intent.putExtra(EntranceConsts.KEY_GAMEID, gameId)
            intent.putExtra(EntranceConsts.KEY_ENTRANCE, mergeEntranceAndPath(entrance, path))
            intent.putExtra(EntranceConsts.KEY_PATH, path)
            intent.putExtra(EntranceConsts.KEY_CREATE_GAME_COLLECTION, true)
            return intent
        }
    }
}