package com.gh.gamecenter.gamedetail.rating

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.LinearLayout
import android.widget.RelativeLayout
import androidx.core.content.ContextCompat
import androidx.core.widget.doOnTextChanged
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.exposure.ExposureManager
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.NewLogUtils
import com.gh.common.util.SyncDataBetweenPageHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
import com.gh.gamecenter.common.baselist.ListActivity
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.CustomDividerItemDecoration
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.KeyboardHeightObserver
import com.gh.gamecenter.core.utils.KeyboardHeightProvider
import com.gh.gamecenter.core.utils.PageSwitchDataHelper
import com.gh.gamecenter.databinding.ActivityRatingReplyBinding
import com.gh.gamecenter.databinding.PieceArticleInputContainerBinding
import com.gh.gamecenter.databinding.PieceCommentTypingContainerBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.entity.RatingComment
import com.gh.gamecenter.entity.RatingReplyEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.utils.Util_System_Keyboard
import com.lightgame.utils.Utils
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import kotlin.math.abs

class RatingReplyActivity : ListActivity<RatingReplyEntity, RatingReplyViewModel>(),
    KeyboardHeightObserver {

    private lateinit var mBinding: ActivityRatingReplyBinding
    private lateinit var mInputBinding: PieceCommentTypingContainerBinding
    private lateinit var mInputPlaceholderBinding: PieceArticleInputContainerBinding

    private var mAdapter: RatingReplyAdapter? = null

    private var mProcessingDialog: WaitingDialogFragment? = null
    private var mReadyReplyData: RatingReplyEntity? = null

    private var mKeyboardHeightProvider: KeyboardHeightProvider? = null
    private var mOffset = 0

    private val dataWatcher = object : DataWatcher() {
        override fun onDataChanged(downloadEntity: DownloadEntity) {
            if (downloadEntity.gameId == mListViewModel?.game?.id) {
                mAdapter?.notifyItemChanged(0)
            }
        }

        override fun onDataInit(downloadEntity: DownloadEntity) {
            onDataChanged(downloadEntity)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == RatingFragment.RATING_PATCH_REQUEST && resultCode == Activity.RESULT_OK) {
            mAdapter?.handleSyncData(requestCode, data)
        }
    }

    override fun getLayoutId() = R.layout.activity_rating_reply

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setNavigationTitle("评价详情")
        initView()
        DisplayUtils.setStatusBarColor(this, R.color.transparent, !mIsDarkModeOn)
    }

    override fun isAutomaticLoad() = false

    override fun provideListAdapter(): RatingReplyAdapter {
        if (mAdapter == null) {
            mAdapter = RatingReplyAdapter(this, mEntrance, mListViewModel, replyCallback = {
                if (it != null) {
                    mInputBinding.answerCommentEt.hint = "回复 @${it.user.name}"
                } else {
                    mInputBinding.answerCommentEt.hint = "回复 @${mListViewModel.comment?.user?.name}"
                }
                mReadyReplyData = it
                mBaseHandler.postDelayed({
                    popInputLayout(true)
                    showKeyboard(true)
                }, 100)
            })
        }
        return mAdapter!!
    }

    override fun getItemDecoration(): RecyclerView.ItemDecoration {
        return CustomDividerItemDecoration(
            this,
            notDecorateTheFirstThreeItems = true,
            notDecorateTheLastTwoItems = true
        ).apply {
            setDrawable(
                ContextCompat.getDrawable(
                    this@RatingReplyActivity,
                    R.drawable.divider_article_detail_comment
                )!!
            )
        }
    }

    override fun provideListViewModel(): RatingReplyViewModel {
        val factory = RatingReplyViewModel.Factory(
            intent.getStringExtra(EntranceConsts.KEY_GAMEID),
            intent.getParcelableExtra(GameEntity::class.java.simpleName),
            intent.getStringExtra(EntranceConsts.KEY_COMMENTID),
            intent.getParcelableExtra(RatingComment::class.java.simpleName),
            intent.getBooleanExtra(EntranceConsts.KEY_SHOW_KEYBOARD_IF_NEEDED, false),
            intent.getStringExtra(EntranceConsts.KEY_TOP_COMMENT_ID) ?: ""
        )
        return ViewModelProviders.of(this, factory).get(RatingReplyViewModel::class.java).apply {
            lastPageData = PageSwitchDataHelper.popLastPageData() ?: hashMapOf()
        }
    }

    private fun initView() {
        mBinding = ActivityRatingReplyBinding.bind(mContentView)
        mInputPlaceholderBinding = mBinding.inputPlaceholderContainer
        mInputBinding = mBinding.inputContainer

        mInputPlaceholderBinding.run {
            bottomCommentIv.visibility = View.GONE
            bottomCommentTv.visibility = View.GONE
            bottomLikeIv.visibility = View.GONE
            bottomLikeTv.visibility = View.GONE
            bottomStarIv.visibility = View.GONE
            bottomStarTv.visibility = View.GONE
            replyTv.setDebouncedClickListener {
                mReadyReplyData = null
                mInputBinding.answerCommentEt.hint = "回复 @${mListViewModel.comment?.user?.name}"
                popInputLayout(true)
                showKeyboard(true)
                logGameDetailCommentDetailCommentClick("回复评价")
            }
        }

        mBinding.reuseNoneData.reuseNoneDataTv.setText(R.string.content_delete_hint)
        mInputBinding.answerCommentSendBtn.setOnClickListener { onViewClick(it) }

        updatePageStatus()
        mListRefresh.isEnabled = false

        mListViewModel.processDialog.observe(this) {
            if (it?.isShow!!) {
                mProcessingDialog = WaitingDialogFragment.newInstance(it.msg, false)
                mProcessingDialog?.show(supportFragmentManager, RatingReplyActivity::class.java.name)
            } else {
                mProcessingDialog?.dismiss()
            }
        }
        mListViewModel.headDataLiveData.observe(this) {
            if (it == true) {
                updatePageStatus()
            }
        }

        mInputBinding.answerCommentSendBtn.run {
            isEnabled = false
            setBackgroundResource(R.drawable.border_round_eee_999)
            setTextColor(R.color.text_body.toColor(this@RatingReplyActivity))
        }
        mInputBinding.answerCommentEt.setHintTextColor(ContextCompat.getColor(this, R.color.hint))
        mInputBinding.answerCommentEt.doOnTextChanged { s, _, _, _ ->
            mInputBinding.answerCommentSendBtn.run {
                if (s.toString().trim().isNotEmpty()) {
                    isEnabled = true
                    setBackgroundResource(R.drawable.button_blue_oval)
                    setTextColor(R.color.white.toColor(this@RatingReplyActivity))
                } else {
                    isEnabled = false
                    setBackgroundResource(R.drawable.border_round_eee_999)
                    setTextColor(R.color.text_body.toColor(this@RatingReplyActivity))
                }
            }
        }

        TextHelper.limitTheLengthOfEditText(
            mInputBinding.answerCommentEt,
            140,
            object : TextHelper.ExceedTextLengthLimitCallback {
                override fun onExceed() {
                    toast("最多140个字")
                }
            })

        if (intent?.getBooleanExtra(EntranceConsts.KEY_OPEN_KEYBOARD, false) == true) {
            popInputLayout(true)
            showKeyboard(true)
        }
        mKeyboardHeightProvider = KeyboardHeightProvider(this)
        mListRv.post { mKeyboardHeightProvider?.start() }
        mBinding.shadowView.setOnClickListener {
            popInputLayout(false)
            showKeyboard(false)
        }
    }

    fun onViewClick(view: View) {
        if (view.id == R.id.answer_comment_send_btn) {
            val entrance = if (mReadyReplyData == null) "${mEntrance}-评论详情-评论" else "${mEntrance}-评论详情-回复"
            ifLogin(entrance) {
                showRegulationTestDialogIfNeeded {
                    val replyContent = mInputBinding.answerCommentEt.text.toString()
                    if (replyContent.isNotEmpty()) {
                        val replyId = if (mReadyReplyData != null) mReadyReplyData?.id else null
                        mListViewModel.replyComment(
                            replyId,
                            replyContent,
                            successCallback = {
                                mInputBinding.answerCommentEt.setText("")
                                mInputBinding.answerCommentEt.clearFocus()
                                popInputLayout(false)
                                showKeyboard(false)
                            }
                        ) { mInputBinding.answerCommentSendBtn.performClick() }
                    } else {
                        Utils.toast(this@RatingReplyActivity, "回复内容不能为空")
                    }
                }
            }
        }
    }

    override fun onLoadRefresh() {
        mReuseNoConn.visibility = View.GONE
        mReuseNoData.visibility = View.GONE
        mListLoading.visibility = View.VISIBLE
        mListViewModel.initData()
    }

    override fun onLoadNotFound() {
        super.onLoadNotFound()
        mInputPlaceholderBinding.root.visibility = View.GONE
        mInputBinding.root.visibility = View.GONE
        mKeyboardHeightProvider?.close()
    }

    private fun updatePageStatus() {
        if (mListViewModel.comment != null && mListViewModel.game != null) {
            mListLoading.visibility = View.GONE
            mInputBinding.answerCommentEt.hint = "回复 @${mListViewModel.comment?.user?.name}"
            mInputPlaceholderBinding.replyTv.text = "回复 @${mListViewModel.comment?.user?.name}"
            mInputPlaceholderBinding.root.visibility = View.VISIBLE
        } else {
            mListLoading.visibility = View.VISIBLE
            mInputPlaceholderBinding.root.visibility = View.GONE
        }
    }

    override fun onResume() {
        super.onResume()
        DownloadManager.getInstance().addObserver(dataWatcher)
        mKeyboardHeightProvider?.setKeyboardHeightObserver(this)
    }

    override fun onPause() {
        super.onPause()
        mAdapter?.getEventByPosition(0)?.let {
            ExposureManager.log(it)
        }
        DownloadManager.getInstance().removeObserver(dataWatcher)
        mKeyboardHeightProvider?.setKeyboardHeightObserver(null)
    }

    override fun onDestroy() {
        super.onDestroy()
        mKeyboardHeightProvider?.close()
    }

    override fun handleBackPressed(): Boolean {
        logGameDetailCommentDetailCommentClick("返回")
        if (SyncDataBetweenPageHelper.setResultAndFinish(this, mListViewModel.comment)) {
            return true
        }
        return super.handleBackPressed()
    }

    override fun onFinish() {
        val stayTime = (System.currentTimeMillis() - startPageTime) / 1000
        NewFlatLogUtils.logGameDetailCommentDetailPageView(
            stayTime,
            mListViewModel?.game?.name ?: "",
            mListViewModel?.game?.id ?: "",
            mListViewModel?.commentId ?: ""
        )
    }

    private fun logGameDetailCommentDetailCommentClick(button: String) {
        mListViewModel?.run {
            val location = when {
                lastPageData.contains(EntranceConsts.KEY_LOCATION) -> lastPageData[EntranceConsts.KEY_LOCATION]
                mEntrance.contains("安利墙") -> "安利墙"
                else -> "其他"
            }
            val tag = if (location == "全部评价") lastPageData[EntranceConsts.KEY_SORT] else ""
            val filter = if (location == "全部评价") lastPageData[EntranceConsts.KEY_FILTER] else ""
            NewFlatLogUtils.logGameDetailCommentDetailCommentClick(
                location ?: "",
                tag ?: "",
                filter ?: "",
                button,
                game?.name ?: "",
                game?.id ?: "",
                commentId ?: ""
            )
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(status: EBDownloadStatus?) {
        if ("delete" == status?.status) {
            mAdapter?.notifyItemChanged(0)
        }
    }

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

    override fun onKeyboardHeightChanged(height: Int, orientation: Int) {
        if (height <= 0) {
            mOffset = abs(height)
        }
        val mLayoutParams = mInputBinding.answerCommentContentContainer.layoutParams as RelativeLayout.LayoutParams
        mLayoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT
        mLayoutParams.bottomMargin = if (height > 0) height + mOffset else 0
        mInputBinding.answerCommentContentContainer.layoutParams = mLayoutParams
    }

    private fun popInputLayout(isPopup: Boolean) {
        mInputPlaceholderBinding.root.goneIf(isPopup)
        mInputBinding.root.goneIf(!isPopup)
        mInputBinding.commentLine.goneIf(isPopup)
        mBinding.shadowView.goneIf(!isPopup)
        mInputBinding.answerContent.orientation = if (isPopup) LinearLayout.VERTICAL else LinearLayout.HORIZONTAL
        if (isPopup) {
            mInputBinding.answerContent.background =
                ContextCompat.getDrawable(this, R.drawable.bg_shape_white_radius_10_top_only)
        } else {
            mInputBinding.answerContent.setBackgroundColor(ContextCompat.getColor(this, R.color.background_white))
        }
        DisplayUtils.setLightStatusBar(this, !isPopup && !mIsDarkModeOn)

        mInputBinding.placeholderView.goneIf(!isPopup)

        val mScrollViewParams = mInputBinding.scrollView.layoutParams as LinearLayout.LayoutParams
        mScrollViewParams.width = if (isPopup) LinearLayout.LayoutParams.MATCH_PARENT else 0
        mScrollViewParams.height = if (isPopup) 76f.dip2px() else 28f.dip2px()
        mScrollViewParams.topMargin = if (isPopup) 8f.dip2px() else 0
        mInputBinding.scrollView.layoutParams = mScrollViewParams
    }

    private fun showKeyboard(isShow: Boolean) {
        if (isShow) {
            mInputBinding.answerCommentEt.requestFocus()
            Util_System_Keyboard.showSoftKeyboard(this, mInputBinding.answerCommentEt)
        } else {
            Util_System_Keyboard.hideSoftKeyboard(this, mInputBinding.answerCommentEt)
        }
    }

    override fun onStop() {
        super.onStop()
        val stayTime = (System.currentTimeMillis() - startPageTime) / 1000
        NewLogUtils.logGameDetailTabOrCommentDetailPause(
            "jump_game_comment_detail",
            stayTime,
            mListViewModel?.game?.id ?: "",
            mListViewModel?.game?.gameType ?: ""
        )
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        mBinding.root.setRootBackgroundColor(R.color.background)
        mBinding.statusBarView.setBackgroundColor(R.color.background_white.toColor(this))
        if (mListRv != null) {
            mListRv.recycledViewPool.clear()
            mAdapter?.notifyItemRangeChanged(0, mAdapter?.itemCount ?: 0)
            if (mListRv.itemDecorationCount > 0) {
                mListRv.removeItemDecorationAt(0)
                mListRv.addItemDecoration(itemDecoration)
            }
        }
        DisplayUtils.setStatusBarColor(this, R.color.transparent, !mIsDarkModeOn)
        mInputBinding.answerContent.background = R.drawable.bg_shape_white_radius_10_top_only.toDrawable(this)
        mInputBinding.answerCommentSendBtn.background = R.drawable.comment_send_button_selector.toDrawable(this)
        mInputBinding.answerCommentSendBtn.setTextColor(R.color.comment_send_btn_selector.toColor(this))
    }

    companion object {
        @JvmStatic
        fun getIntent(
            context: Context,
            game: GameEntity,
            comment: RatingComment,
            entrance: String,
            path: String
        ): Intent {
            val intent = Intent(context, RatingReplyActivity::class.java)
            intent.putExtra(EntranceConsts.KEY_ENTRANCE, mergeEntranceAndPath(entrance, path))
            intent.putExtra(GameEntity::class.java.simpleName, game)
            intent.putExtra(RatingComment::class.java.simpleName, comment)
            return intent
        }

        @JvmStatic
        fun getIntent(
            context: Context,
            gameId: String,
            comment: RatingComment,
            showKeyboardIfReplyListIsEmpty: Boolean,
            entrance: String,
            path: String
        ): Intent {
            val intent = Intent(context, RatingReplyActivity::class.java)
            intent.putExtra(EntranceConsts.KEY_ENTRANCE, mergeEntranceAndPath(entrance, path))
            intent.putExtra(EntranceConsts.KEY_GAMEID, gameId)
            intent.putExtra(RatingComment::class.java.simpleName, comment)
            intent.putExtra(EntranceConsts.KEY_SHOW_KEYBOARD_IF_NEEDED, showKeyboardIfReplyListIsEmpty)
            return intent
        }

        @JvmStatic
        fun getIntent(
            context: Context,
            gameId: String,
            commentId: String,
            entrance: String,
            path: String
        ): Intent {
            return getIntent(context, gameId, commentId, "", false, entrance, path)
        }

        @JvmStatic
        fun getIntent(
            context: Context,
            gameId: String,
            commentId: String,
            showKeyboardIfReplyListIsEmpty: Boolean,
            entrance: String,
            path: String
        ): Intent {
            return getIntent(context, gameId, commentId, "", showKeyboardIfReplyListIsEmpty, entrance, path)
        }

        @JvmStatic
        fun getSpecifiedCommentIntent(
            context: Context,
            gameId: String,
            commentId: String,
            topCommentId: String,
            entrance: String,
            path: String
        ): Intent {
            return getIntent(context, gameId, commentId, topCommentId, false, entrance, path)
        }

        @JvmStatic
        fun getIntent(
            context: Context,
            gameId: String,
            commentId: String,
            topCommentId: String,
            showKeyboardIfReplyListIsEmpty: Boolean,
            entrance: String,
            path: String
        ): Intent {
            val intent = Intent(context, RatingReplyActivity::class.java)
            intent.putExtra(EntranceConsts.KEY_ENTRANCE, mergeEntranceAndPath(entrance, path))
            intent.putExtra(EntranceConsts.KEY_GAMEID, gameId)
            intent.putExtra(EntranceConsts.KEY_COMMENTID, commentId)
            intent.putExtra(EntranceConsts.KEY_TOP_COMMENT_ID, topCommentId)
            intent.putExtra(EntranceConsts.KEY_SHOW_KEYBOARD_IF_NEEDED, showKeyboardIfReplyListIsEmpty)
            return intent
        }

        @JvmStatic
        fun getOpenKeyboardIntent(
            context: Context,
            game: GameEntity,
            comment: RatingComment,
            entrance: String,
            path: String
        ): Intent {
            val intent = Intent(context, RatingReplyActivity::class.java)
            intent.putExtra(EntranceConsts.KEY_ENTRANCE, mergeEntranceAndPath(entrance, path))
            intent.putExtra(GameEntity::class.java.simpleName, game)
            intent.putExtra(RatingComment::class.java.simpleName, comment)
            intent.putExtra(EntranceConsts.KEY_OPEN_KEYBOARD, true)
            return intent
        }
    }

    override fun getBusinessId(): Pair<String, String> {
        return if (intent.getStringExtra(EntranceConsts.KEY_COMMENTID) != null) {
            Pair(intent.getStringExtra(EntranceConsts.KEY_COMMENTID) ?: "", "")
        } else {
            super.getBusinessId()
        }
    }
}