package com.gh.gamecenter.personal

import android.annotation.SuppressLint
import android.content.Intent
import android.database.sqlite.SQLiteException
import android.os.*
import android.text.TextUtils
import android.view.MotionEvent
import android.view.View
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
import androidx.viewpager2.widget.ViewPager2
import com.gh.common.constant.Config
import com.gh.common.databind.BindingAdapters
import com.gh.common.util.*
import com.gh.common.util.DialogUtils
import com.gh.common.util.LogUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.*
import com.gh.gamecenter.common.base.fragment.BaseLazyFragment
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.retrofit.ApiResponse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration
import com.gh.gamecenter.common.view.ScrollEventListener
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.FragmentHaloPersonalBinding
import com.gh.gamecenter.databinding.FragmentPersonalStubBinding
import com.gh.gamecenter.entity.BadgeEntity
import com.gh.gamecenter.entity.MessageUnreadEntity
import com.gh.gamecenter.eventbus.EBConcernChanged
import com.gh.gamecenter.eventbus.EBNetworkState
import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.gamecollection.mine.MyGameCollectionActivity
import com.gh.gamecenter.history.HistoryActivity
import com.gh.gamecenter.login.entity.Badge
import com.gh.gamecenter.login.entity.UserInfoEntity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.user.UserViewModel
import com.gh.gamecenter.login.utils.LoginHelper
import com.gh.gamecenter.message.MessageUnreadRepository
import com.gh.gamecenter.message.MessageUnreadViewModel
import com.gh.gamecenter.mygame.MyGameActivity
import com.gh.gamecenter.mypost.MyPostActivity
import com.gh.gamecenter.personalhome.UserHomeViewModel
import com.gh.gamecenter.room.AppDatabase
import com.gh.gamecenter.setting.SettingBridge
import com.google.android.material.appbar.AppBarLayout
import com.halo.assistant.HaloApp
import com.jakewharton.rxbinding2.view.RxView
import com.tencent.connect.common.Constants
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.lang.ref.WeakReference
import java.util.concurrent.TimeUnit
import kotlin.math.abs

class HaloPersonalFragment : BaseLazyFragment() {
    private var mUserInfoEntity: UserInfoEntity? = null

    private lateinit var mDatabase: AppDatabase

    private lateinit var mBinding: FragmentPersonalStubBinding
    private lateinit var mStubBinding: FragmentHaloPersonalBinding
    private lateinit var mUserViewModel: UserViewModel
    private lateinit var mUnreadViewModel: MessageUnreadViewModel
    private lateinit var mUserHomeViewModel: UserHomeViewModel
    private lateinit var mHaloPersonalViewModel: HaloPersonalViewModel

    private lateinit var mPersonalRecommendAdapter: HaloPersonalRecommendAdapter
    private lateinit var mPersonalBannerAdapter: HaloPersonalBannerAdapter
    private lateinit var mPersonalFunctionAdapter: HaloPersonalFunctionAdapter

    private lateinit var mSnapHelper: PagerSnapHelper
    private lateinit var mBannerLayoutManager: LinearLayoutManager
    private val mLooperHandle = LooperHandle(this)
    private val mSlideLooperKey = 101

    private var mIsLogging = false

    override fun getInflatedLayout(): View {
        mBinding = FragmentPersonalStubBinding.inflate(layoutInflater, null, false)
        mBinding.stub.setOnInflateListener { _, inflateId ->
            mStubBinding = FragmentHaloPersonalBinding.bind(inflateId)
        }
        return mBinding.root
    }

    override fun getLayoutId() = R.layout.fragment_personal_stub

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            Constants.REQUEST_LOGIN -> {
                LoginHelper.onQQLoginCallback(requestCode, resultCode, data)
            }
            32973 -> {
                LoginHelper.onWeiboLoginCallback(requireActivity(), requestCode, resultCode, data)
            }
            REQUEST_MESSAGE -> {
                mUnreadViewModel.retry()
            }
        }
    }

    override fun onClick(v: View?) {
        super.onClick(v)
        when (v) {
            mStubBinding.motionLayout -> {
                if (mUserInfoEntity == null) {
                    NewFlatLogUtils.logHaloSelfLogin()
                    CheckLoginUtils.checkLogin(context, "我的光环-立即登录", null)
                } else {
                    mStubBinding.ivArrow.performClick()
                }
            }
            mStubBinding.toolbarContainer -> {
                if (mUserInfoEntity == null) {
                    NewFlatLogUtils.logHaloSelfLogin()
                    CheckLoginUtils.checkLogin(context, "我的光环-立即登录", null)
                }
            }
            mStubBinding.darkModeIv -> {
                if (!ClickUtils.isFastDoubleClick(v.id, 1000)) {
                    NewFlatLogUtils.logHaloSelfClick("右上角", "切换模式")
                    if (DarkModeUtils.isFollowSystemDarkModeFromSp()) {
                        DialogHelper.showDialog(
                            context = requireContext(),
                            title = "提示",
                            content = "切换模式后，将暂时关闭深色模式跟随系统切换功能，您可以前往“我的光环-设置”再次开启。",
                            confirmText = "确定",
                            cancelText = "取消",
                            confirmClickCallback = {
                                NewFlatLogUtils.logHaloSelfNightModeOsDialog("确定")
                                DarkModeUtils.updateAppDarkModeStatusToSp(!mIsDarkModeOn)
                                DarkModeUtils.updateFollowSystemDarkModeToSp(false)
                                DarkModeUtils.initDarkMode()
                            }, cancelClickCallback = {
                                NewFlatLogUtils.logHaloSelfNightModeOsDialog("关闭弹窗")
                            }, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
                        )?.setOnCancelListener {
                            NewFlatLogUtils.logHaloSelfNightModeOsDialog("关闭弹窗")
                        }
                    } else {
                        NewFlatLogUtils.logHaloSelfNightModeClick(if (mIsDarkModeOn) "日间模式" else "深色模式")
                        DarkModeUtils.updateAppDarkModeStatusToSp(!mIsDarkModeOn)
                        DarkModeUtils.initDarkMode()
                    }
                }
            }
            mStubBinding.personalMsg -> {
                if (CheckLoginUtils.isLogin()) {
                    NewFlatLogUtils.logHaloSelfClick("右上角", "消息中心")
                    NewLogUtils.logMessageInformBellClick(
                        mStubBinding.loginMessageHint.visibility == View.VISIBLE,
                        "我的"
                    )
                    startActivityForResult(
                        MessageActivity.getIntent(context, "(我的光环)+(消息中心)"),
                        REQUEST_MESSAGE
                    )
                } else {
                    NewFlatLogUtils.logHaloSelfLogin()
                    CheckLoginUtils.checkLogin(context, "我的光环-消息") {}
                }
            }
            mStubBinding.personalUserIcon,
            mStubBinding.personalUserName -> {
                if (mUserInfoEntity != null) {
                    DirectUtils.directToHomeActivity(
                        requireContext(),
                        UserManager.getInstance().userId,
                        "",
                        "我的光环"
                    )
                } else {
                    NewFlatLogUtils.logHaloSelfLogin()
                    CheckLoginUtils.checkLogin(context, "我的光环-立即登录", null)
                }
            }
            mStubBinding.ivArrow -> {
                if (mUserInfoEntity != null) {
                    DirectUtils.directToHomeActivity(
                        requireContext(),
                        UserManager.getInstance().userId,
                        "",
                        "我的光环"
                    )
                } else {
                    CheckLoginUtils.checkLogin(context, "我的光环-个人主页", null)
                }
            }
            mStubBinding.personalBadge -> {
                DirectUtils.directToBadgeWall(
                    requireContext(),
                    mUserInfoEntity?.userId,
                    mUserInfoEntity?.name,
                    mUserInfoEntity?.icon
                )
            }
            mStubBinding.myGameTv -> {
                if (UserManager.getInstance().isLoggedIn) {
                    NewFlatLogUtils.logHaloSelfClick("常用功能", "我的游戏")
                    startActivity(Intent(requireContext(), MyGameActivity::class.java))
                } else {
                    NewFlatLogUtils.logHaloSelfLogin()
                    CheckLoginUtils.checkLogin(requireContext(), "我的光环-我的游戏") {}
                }
            }
            mStubBinding.myPostTv -> {
                if (UserManager.getInstance().isLoggedIn) {
                    NewFlatLogUtils.logHaloSelfClick("常用功能", "我的发布")
                    startActivity(MyPostActivity.getIntent(requireContext(), "我的光环-我的发布"))
                } else {
                    NewFlatLogUtils.logHaloSelfLogin()
                    CheckLoginUtils.checkLogin(requireContext(), "我的光环-我的发布") { }
                }
            }
            mStubBinding.myGameCollectionTv -> {
                if (UserManager.getInstance().isLoggedIn) {
                    NewFlatLogUtils.logHaloSelfClick("常用功能", "我的游戏单")
                    startActivity(MyGameCollectionActivity.getIntent(requireContext()))
                } else {
                    NewFlatLogUtils.logHaloSelfLogin()
                    CheckLoginUtils.checkLogin(requireContext(), "我的光环-我的游戏单") { }
                }
            }
            mStubBinding.historyTv -> {
                NewFlatLogUtils.logHaloSelfClick("常用功能", "浏览记录")
                startActivity(HistoryActivity.getHistoryIntent(requireContext(), "我的光环-浏览记录"))
            }
            mStubBinding.myCollectionTv -> {
                if (UserManager.getInstance().isLoggedIn) {
                    NewFlatLogUtils.logHaloSelfClick("常用功能", "我的收藏")
                    if ((MessageUnreadRepository.addonsUnread.value?.favorite ?: 0) > 0) {
                        MessageUnreadRepository.refreshUnreadCount(MessageUnreadRepository.UnreadMessageType.FAVORITE)
                    }
                    startActivity(CollectionActivity.getCollectionActivity(requireContext(), "(我的光环)"))
                } else {
                    NewFlatLogUtils.logHaloSelfLogin()
                    CheckLoginUtils.checkLogin(requireContext(), "我的光环-我的收藏") {}
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mDatabase = AppDatabase.getInstance()
        val factory = UserViewModel.Factory(requireActivity().application)
        mUserViewModel = ViewModelProvider(this, factory).get(UserViewModel::class.java)
        mUserHomeViewModel = ViewModelProvider(
            this, UserHomeViewModel.Factory(
                HaloApp.getInstance().application,
                UserManager.getInstance().userId
            )
        ).get(UserHomeViewModel::class.java)
        mUnreadViewModel = ViewModelProvider(
            this,
            MessageUnreadViewModel.Factory(HaloApp.getInstance().application)
        ).get(MessageUnreadViewModel::class.java)
        mHaloPersonalViewModel = ViewModelProvider(this).get(HaloPersonalViewModel::class.java)

        observeNoneUIRelatedChanges()
    }

    override fun onFragmentFirstVisible() {
        super.onFragmentFirstVisible()
        inflateRealView()
        observeUIRelatedChanges()
    }

    override fun onFragmentResume() {
        super.onFragmentResume()

        if (NetworkUtils.isNetworkConnected(requireContext())) {
            mUnreadViewModel.retry()
            mUserHomeViewModel.getBadgeList()
            mUserHomeViewModel.availableBadges()
        }
        val currentItem = (parentFragment as MainWrapperFragment).currentItem
        if (currentItem == MainWrapperFragment.INDEX_PERSONAL) {
            DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn)
        }
    }

    @SuppressLint("CheckResult", "SetTextI18n")
    private fun observeUIRelatedChanges() {
        mHaloPersonalViewModel.appEntity.observe(this) {
            mStubBinding.settingItem.newVersionTv.goneIf(it.versionCode <= PackageUtils.getGhVersionCode())
        }
        mHaloPersonalViewModel.recommendData.observeNonNull(this) {
            if (it.size > 1) {
                mStubBinding.recommendRv.visibility = View.VISIBLE
                mPersonalRecommendAdapter.setRecommendList(it.take(if (it.size < MAX_RECOMMEND_COUNT) 2 else MAX_RECOMMEND_COUNT))
            } else {
                mStubBinding.recommendRv.visibility = View.GONE
            }
        }
        mHaloPersonalViewModel.activityData.observeNonNull(this) {
            if (it.isNotEmpty()) {
                mStubBinding.bannerContainer.visibility = View.VISIBLE
                mPersonalBannerAdapter.submitList(it)
                if (mPersonalBannerAdapter.getActualSize() > 1) {
                    mStubBinding.bannerRv.scrollToPosition(mPersonalBannerAdapter.getActualFirstPositionInCenter())
                }
                mStubBinding.bannerIndicator.run {
                    mPageSize = mPersonalBannerAdapter.getActualSize()
                    notifyDataChanged()
                }
                startBannerAutoPlay()
            } else {
                mStubBinding.bannerContainer.visibility = View.GONE
            }
        }
        mHaloPersonalViewModel.moreFeaturesData.observeNonNull(this) {
            if (it.isNotEmpty()) {
                mStubBinding.functionContainer.visibility = View.VISIBLE
                mPersonalFunctionAdapter.setFunctionList(it.take(MAX_MORE_FEATURES_COUNT))
            } else {
                mStubBinding.functionContainer.visibility = View.GONE
            }
        }

        mUserViewModel.loginObsUserinfo.observe(
            this
        ) { userInfoEntity: ApiResponse<UserInfoEntity?>? ->
            if (userInfoEntity != null && userInfoEntity.data != null) {
                changeLoginState(true)
            } else {
                changeLoginState(false)
            }
        }

        mUserHomeViewModel.badges.observe(
            this
        ) { badgeEntities: List<BadgeEntity> ->
            mStubBinding.personalBadgeIcon.setImageURI("")
            if (badgeEntities.isEmpty()) {
                mStubBinding.personalBadgeCountTv.text = "我的徽章"
            } else {
                mStubBinding.personalBadgeCountTv.text = "${badgeEntities.size} 徽章"
                for ((_, _, icon, name, _, wear, _, actions) in badgeEntities) {
                    if (wear) {
                        ImageUtils.display(
                            mStubBinding.personalBadgeIcon,
                            icon
                        )
                        mStubBinding.personalBadgeIcon.setOnClickListener {
                            DialogUtils.showViewBadgeDialog(requireContext(), Badge(name, icon, actions)) {
                                DirectUtils.directToBadgeWall(
                                    requireContext(),
                                    mUserInfoEntity?.userId,
                                    mUserInfoEntity?.name,
                                    mUserInfoEntity?.icon
                                )
                            }
                        }
                        break
                    }
                }
            }
        }
        mUserHomeViewModel.availableBadgeCount.observe(this) { count: Int ->
            mStubBinding.personalBadgeTips.visibility =
                if (count > 0) View.VISIBLE else View.GONE
        }

        mUserHomeViewModel.availableBadge.observe(this) { badge: BadgeEntity? ->
            // 徽章领取弹窗每隔7天弹出一次，所以要判断现在是否是上一次弹出的第7天或者之后
            if (badge != null && System.currentTimeMillis() >= SPUtils.getLong(SP_BADGE_RECORD_SEVEN_DAY)) {
                // 徽章领取弹窗每隔7天弹出一次，所以本次弹出后就记录7天后的时间戳
                SPUtils.setLong(
                    SP_BADGE_RECORD_SEVEN_DAY,
                    TimeUtils.getStartTimeOfDay(System.currentTimeMillis() + 86400000 * 6)
                )
                DialogUtils.showReceiveBadgeDialog(requireContext(), badge) {
                    mHaloPersonalViewModel.applyOrReceiveBadge(badge.id, {
                        if ("self" == badge.receive?.type) {
                            ToastUtils.showToast("领取成功")
                        } else {
                            ToastUtils.showToast("申请成功")
                        }
                        // 跳转到徽章详情
                        DirectUtils.directToBadgeDetail(
                            requireContext(),
                            mUserInfoEntity?.userId,
                            badge.id
                        )
                    }, {
                        if ("self" == badge.receive?.type) {
                            ToastUtils.showToast("领取失败")
                        } else {
                            ToastUtils.showToast("申请失败")
                        }
                    })
                }
            }
        }

        mUnreadViewModel.liveData.observe(this) { messageUnread: MessageUnreadEntity? ->
            if (messageUnread != null && messageUnread.total > 0) {
                val count = messageUnread.total - messageUnread.fans
                mStubBinding.loginMessageHint.visibility =
                    if (count > 0) View.VISIBLE else View.GONE
                BindingAdapters.setMessageUnread(mStubBinding.loginMessageHint, count)
            } else {
                mStubBinding.loginMessageHint.visibility = View.GONE
                EventBus.getDefault()
                    .post(EBReuse(MESSAGE_READ_OVER))
            }
        }

        // 微信/签到
        RxView.clicks(mStubBinding.personalSign)
            .throttleFirst(1, TimeUnit.SECONDS)
            .subscribe {
                if (CheckLoginUtils.isLogin()) {
                    NewFlatLogUtils.logHaloSelfClick("右上角", "签到")
                    sign()
                } else {
                    NewFlatLogUtils.logHaloSelfLogin()
                    CheckLoginUtils.checkLogin(context, "我的光环-签到") {}
                }
            }
    }

    private fun sign() {
        mHaloPersonalViewModel.sign { signEntity ->
            if (mHaloPersonalViewModel.isCanSign(signEntity.lastTime)) {
                DialogUtils.showSignDialog(
                    context,
                    "签到成功，获得经验：1",
                    getString(R.string.sign_dialog_content, signEntity.serialSign),
                    getString(R.string.sign_dialog_content2, signEntity.experience),
                    getSignSkipText(signEntity.title)
                ) { mHaloPersonalViewModel.signSkip(signEntity) }
                signEntity.lastTime = System.currentTimeMillis() / 1000
            } else {
                DialogUtils.showSignDialog(
                    context,
                    "今天已签到，明天再来吧~",
                    getString(R.string.sign_dialog_content, signEntity.serialSign),
                    getString(R.string.sign_dialog_content2, signEntity.experience),
                    getSignSkipText(signEntity.title)
                ) { mHaloPersonalViewModel.signSkip(signEntity) }
            }
            signEntity.id = UserManager.getInstance().userId
            if (mDatabase.signDao().updateSignEntity(signEntity) <= 0) {
                try {
                    mDatabase.signDao().addSignEntity(signEntity)
                } catch (e: SQLiteException) {
                    e.printStackTrace()
                }
            }
        }
    }

    private fun getSignSkipText(text: String): String =
        if (TextUtils.isEmpty(text)) "去首页看看" else text

    @SuppressLint("SetTextI18n")
    private fun changeLoginState(isLogin: Boolean) {
        if (isLogin) {
            if (mUserInfoEntity != null) {
                mStubBinding.personalUserIcon.display(
                    if (mUserInfoEntity?.iconBorder == null) "" else mUserInfoEntity?.iconBorder?.url,
                    mUserInfoEntity?.icon,
                    null
                )
                mStubBinding.motionLayout.run {
                    getConstraintSet(R.id.start).run {
                        setVisibility(R.id.personal_badge, View.VISIBLE)
                        clear(R.id.personal_user_name, ConstraintSet.BOTTOM)
                        setMargin(R.id.personal_user_name, ConstraintSet.TOP, 14F.dip2px())
                        setMargin(R.id.userIdTv, ConstraintSet.TOP, 0)
                    }
                    getConstraintSet(R.id.end).run {
                        setVisibility(R.id.personal_badge, View.VISIBLE)
                    }
                }
                mStubBinding.userIdTv.textSize = 10F
                mStubBinding.personalUserName.text = mUserInfoEntity?.name
                mStubBinding.userIdTv.text = "ID:${mUserInfoEntity?.getShortUserId()}"
                mStubBinding.userIdTv.setOnLongClickListener {
                    mStubBinding.userIdTv.text.toString().substring(3).copyTextAndToast("用户ID复制成功")
                    return@setOnLongClickListener true
                }
            }
            mUserHomeViewModel.userId = UserManager.getInstance().userId
            mUserHomeViewModel.getBadgeList()
            mUserHomeViewModel.availableBadges()
            MessageUnreadRepository.loadMessageUnreadTotal(true)
        } else {
            mStubBinding.personalUserIcon.display("", "", "")
            mStubBinding.motionLayout.run {
                getConstraintSet(R.id.start).run {
                    setVisibility(R.id.personal_badge, View.GONE)
                    setVerticalChainStyle(R.id.personal_user_name, ConstraintSet.CHAIN_PACKED)
                    setVerticalChainStyle(R.id.userIdTv, ConstraintSet.CHAIN_PACKED)
                    connect(R.id.personal_user_name, ConstraintSet.BOTTOM, R.id.userIdTv, ConstraintSet.TOP)
                    setMargin(R.id.personal_user_name, ConstraintSet.TOP, 0)
                    setMargin(R.id.userIdTv, ConstraintSet.TOP, 3F.dip2px())
                }
                getConstraintSet(R.id.end).run {
                    setVisibility(R.id.personal_badge, View.GONE)
                }
            }

            mStubBinding.userIdTv.textSize = 11F
            mStubBinding.personalUserName.text = "立即登录"
            mStubBinding.userIdTv.text = "解锁更多精彩内容"

            if (mStubBinding.loginMessageHint.visibility == View.VISIBLE) {
                mStubBinding.loginMessageHint.visibility = View.GONE
                EventBus.getDefault().post(EBReuse(MESSAGE_READ_OVER))
            }
        }
    }

    private fun inflateRealView() {
        mBinding.stub.inflate()

        mStubBinding.statusBar.goneIf(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
        mStubBinding.darkModeIv.goneIf(!(Config.getNightModeSetting()?.icon ?: false))
        mStubBinding.darkModeIv.setImageResource(if (mIsDarkModeOn) R.drawable.ic_personal_light_mode else R.drawable.ic_personal_dark_mode)
        mStubBinding.ivArrow.enlargeTouchArea()

        mStubBinding.motionLayout.setOnClickListener(this)
        mStubBinding.toolbarContainer.setOnClickListener(this)
        mStubBinding.darkModeIv.setOnClickListener(this)
        mStubBinding.personalMsg.setOnClickListener(this)
        mStubBinding.ivArrow.setOnClickListener(this)
        mStubBinding.personalUserName.setOnClickListener(this)
        mStubBinding.personalUserIcon.setOnClickListener(this)
        mStubBinding.personalBadge.setOnClickListener(this)
        mStubBinding.myGameTv.setOnClickListener(this)
        mStubBinding.myPostTv.setOnClickListener(this)
        mStubBinding.myGameCollectionTv.setOnClickListener(this)
        mStubBinding.historyTv.setOnClickListener(this)
        mStubBinding.myCollectionTv.setOnClickListener(this)

        val statusBarHeight =
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) 0 else DisplayUtils.getStatusBarHeight(resources)
        mStubBinding.motionLayout.minimumHeight = statusBarHeight + 48F.dip2px()

        mStubBinding.appbar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { _: AppBarLayout?, verticalOffset: Int ->
            mStubBinding.listRefresh.isEnabled = abs(verticalOffset) <= 2
        })

        mStubBinding.listRefresh.setColorSchemeColors(
            ContextCompat.getColor(
                requireContext(),
                R.color.theme
            )
        )
        mStubBinding.listRefresh.setProgressViewOffset(
            false,
            0,
            DisplayUtils.dip2px(80F) + DisplayUtils.getStatusBarHeight(requireContext().resources)
        )
        mStubBinding.listRefresh.setOnRefreshListener {
            mHaloPersonalViewModel.getHaloAddons(true)
            if (CheckLoginUtils.isLogin()) {
                mUnreadViewModel.retry()
                MessageUnreadRepository.loadMessageUnreadTotal(false)
                mUserHomeViewModel.getBadgeList()
                mUserHomeViewModel.availableBadges()
            }
            mBaseHandler.postDelayed({ mStubBinding.listRefresh.isRefreshing = false }, 2000)
        }
        MessageUnreadRepository.loadMessageUnreadTotal(true)

        initRecommendRv()
        initActivityBanner()
        initMoreFeaturesRv()
        initSettingItems()
    }

    private fun initSettingItems() {
        mStubBinding.settingItem.run {
            titleTv.text = getString(R.string.title_settings)
            iconIv.setImageResource(R.drawable.ic_personal_setting)
            root.setOnClickListener {
                NewFlatLogUtils.logHaloSelfClick("其他功能", "设置")
                startActivity(SettingBridge.getSettingIntent(requireContext(), false, "我的光环"))
            }
        }
        mStubBinding.feedbackItem.run {
            titleTv.text = "帮助与反馈"
            iconIv.setImageResource(R.drawable.ic_personal_feedback)
            root.setOnClickListener {
                NewFlatLogUtils.logHaloSelfClick("其他功能", "帮助与反馈")
                DirectUtils.directToHelpAndFeedback(requireContext())
            }
        }
        mStubBinding.shareGhItem.run {
            titleTv.text = "分享光环"
            iconIv.setImageResource(R.drawable.ic_personal_share)
            root.setOnClickListener {
                NewFlatLogUtils.logHaloSelfClick("其他功能", "分享光环")
                startActivity(ShareGhActivity.getIntent(requireContext()))
            }
        }
        mStubBinding.userProtocolItem.run {
            titleTv.text = getString(R.string.setting_user_protocol)
            iconIv.setImageResource(R.drawable.ic_personal_user_protocol)
            root.setOnClickListener {
                NewFlatLogUtils.logHaloSelfClick("其他功能", getString(R.string.setting_user_protocol))
                startActivity(
                    WebActivity.getWebIntent(
                        requireContext(),
                        requireContext().getString(R.string.disclaimer_title),
                        requireContext().getString(R.string.disclaimer_url)
                    )
                )
            }
        }
        mStubBinding.privacyPolicyItem.run {
            titleTv.text = getString(R.string.setting_privacy_policy)
            iconIv.setImageResource(R.drawable.ic_personal_privacy_policy)
            //判断隐私政策是否有更新
            mStubBinding.privacyPolicyItem.redDot.visibility = if (checkPrivacyIsSame()) View.GONE else View.VISIBLE
            root.setOnClickListener {
                NewFlatLogUtils.logHaloSelfClick("其他功能", getString(R.string.setting_privacy_policy))
                SPUtils.setString(
                    com.gh.gamecenter.common.constant.Constants.SP_PRIVACY_MD5,
                    SPUtils.getString(com.gh.gamecenter.common.constant.Constants.SP_PRIVACY_CURRENT_MD5)
                )
                redDot.visibility = if (checkPrivacyIsSame()) View.GONE else View.VISIBLE
                startActivity(
                    WebActivity.getWebIntent(
                        requireContext(),
                        requireContext().getString(R.string.privacy_policy_title),
                        requireContext().getString(R.string.privacy_policy_url)
                    )
                )
            }
        }
        mStubBinding.infoListItem.run {
            titleTv.text = getString(R.string.setting_info_list)
            iconIv.setImageResource(R.drawable.ic_personal_info_list)
            root.setOnClickListener {
                NewFlatLogUtils.logHaloSelfClick("其他功能", getString(R.string.setting_info_list))
                startActivity(
                    WebActivity.getWebIntent(
                        requireContext(),
                        getString(R.string.setting_info_list),
                        requireContext().getString(R.string.info_list_url)
                    )
                )
            }
        }
        mStubBinding.sdkListItem.run {
            titleTv.text = getString(R.string.setting_sdk_list)
            iconIv.setImageResource(R.drawable.ic_personal_sdk)
            root.setOnClickListener {
                NewFlatLogUtils.logHaloSelfClick("其他功能", getString(R.string.setting_sdk_list))
                startActivity(
                    WebActivity.getWebIntent(
                        requireContext(),
                        getString(R.string.setting_sdk_list),
                        requireContext().getString(R.string.sdk_list_url)
                    )
                )
            }
        }
        mStubBinding.permissionAndUsageItem.run {
            titleTv.text = getString(R.string.setting_permission_and_usage)
            iconIv.setImageResource(R.drawable.ic_personal_permission)
            root.setOnClickListener {
                NewFlatLogUtils.logHaloSelfClick("其他功能", getString(R.string.setting_permission_and_usage))
                startActivity(
                    WebActivity.getWebIntent(
                        requireContext(),
                        getString(R.string.setting_permission_and_usage),
                        requireContext().getString(R.string.permission_and_usage_url)
                    )
                )
            }
        }
        mStubBinding.childrenPolicyItem.run {
            titleTv.text = getString(R.string.setting_children_policy)
            iconIv.setImageResource(R.drawable.ic_personal_children_policy)
            root.setOnClickListener {
                NewFlatLogUtils.logHaloSelfClick("其他功能", getString(R.string.setting_children_policy))
                startActivity(
                    WebActivity.getWebIntent(
                        requireContext(),
                        getString(R.string.setting_children_policy),
                        requireContext().getString(R.string.children_policy_url)
                    )
                )
            }
        }
    }

    private fun initRecommendRv() {
        mPersonalRecommendAdapter = HaloPersonalRecommendAdapter(requireContext())
        mStubBinding.recommendRv.layoutManager = GridLayoutManager(requireContext(), 2)
        mStubBinding.recommendRv.adapter = mPersonalRecommendAdapter
    }

    private fun initActivityBanner() {
        mStubBinding.bannerRv.run {
            mPersonalBannerAdapter = HaloPersonalBannerAdapter(requireContext())
            mSnapHelper = PagerSnapHelper()
            mBannerLayoutManager = LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
            adapter = mPersonalBannerAdapter
            layoutManager = mBannerLayoutManager
            mSnapHelper.attachToRecyclerView(this)
            isNestedScrollingEnabled = false
            addOnItemTouchListener(object : RecyclerView.SimpleOnItemTouchListener() {
                override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
                    when (e.action) {
                        MotionEvent.ACTION_DOWN -> {
                            mStubBinding.listRefresh.isEnabled = false
                        }
                        MotionEvent.ACTION_UP -> {
                            mStubBinding.listRefresh.isEnabled = true
                        }
                    }

                    val isStop = e.action == MotionEvent.ACTION_DOWN || e.action == MotionEvent.ACTION_MOVE
                    if (isStop) stopBannerAutoPlay() else startBannerAutoPlay()
                    return false
                }
            })
            addOnScrollListener(ScrollEventListener(this).apply {
                setOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
                    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
                        super.onPageScrolled(position, positionOffset, positionOffsetPixels)
                        mStubBinding.bannerIndicator.onPageScrolled(
                            mPersonalBannerAdapter.getActualPosition(position),
                            positionOffset
                        )
                    }
                })
            })
        }
    }

    private fun scrollToNextPage() {
        val snapView = mSnapHelper.findSnapView(mBannerLayoutManager)
        if (snapView != null) {
            mBannerLayoutManager.smoothScrollToPosition(
                mStubBinding.bannerRv,
                null,
                mBannerLayoutManager.getPosition(snapView) + 1
            )
        }
    }

    private fun startBannerAutoPlay() {
        if (mPersonalBannerAdapter.getActualSize() < 2) return
        stopBannerAutoPlay()
        mLooperHandle.sendEmptyMessageDelayed(mSlideLooperKey, BANNER_LOOP_TIME)
    }

    private fun stopBannerAutoPlay() {
        mLooperHandle.removeMessages(mSlideLooperKey)
    }

    private fun initMoreFeaturesRv() {
        mPersonalFunctionAdapter = HaloPersonalFunctionAdapter(requireContext())
        mStubBinding.funcRv.layoutManager = GridLayoutManager(requireContext(), 4)
        mStubBinding.funcRv.adapter = mPersonalFunctionAdapter
        mStubBinding.funcRv.isNestedScrollingEnabled = false
        mStubBinding.funcRv.addItemDecoration(
            GridSpacingItemColorDecoration(
                requireContext(),
                0,
                18,
                R.color.transparent
            )
        )
    }

    private fun checkPrivacyIsSame(): Boolean {
        val currentMd5 = SPUtils.getString(com.gh.gamecenter.common.constant.Constants.SP_PRIVACY_CURRENT_MD5)
        val privacyMd5 = SPUtils.getString(com.gh.gamecenter.common.constant.Constants.SP_PRIVACY_MD5)
        return currentMd5 == privacyMd5
    }

    private fun observeNoneUIRelatedChanges() {
        mHaloPersonalViewModel.getHaloAddons(false)
        mUserViewModel.loginObsUserinfo.observe(this) { userInfoEntity: ApiResponse<UserInfoEntity>? ->
            val notifyUserInfo: UserInfoEntity? = userInfoEntity?.data
            if (notifyUserInfo != null && mUserInfoEntity == null) { // 单个用户，首次触发
                EventBus.getDefault().post(EBConcernChanged())
                val loginTokenEntity =
                    UserManager.getInstance().loginTokenEntity
                if (mIsLogging && loginTokenEntity != null) {
                    val loginType = loginTokenEntity.loginType
                    LogUtils.login(
                        "success",
                        loginType,
                        mHaloPersonalViewModel.getLoginEntranceByType(loginType)
                    )
                    mIsLogging = false
                }
            }
            mUserInfoEntity = notifyUserInfo
            if (notifyUserInfo == null) {
                mUnreadViewModel.clean()
                EventBus.getDefault().post(EBConcernChanged())
            }
        }
        mHaloPersonalViewModel.haloAddData.observeNonNull(this) {
            if (it.isNotEmpty()) {
                MessageUnreadRepository.loadMessageUnreadTotal(false)
            }
        }
    }

    // 连接上网络事件
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(busNetworkState: EBNetworkState) {
        if (busNetworkState.isNetworkConnected
            && UserManager.getInstance().isLoggedIn
            && (mUserInfoEntity == null || TextUtils.isEmpty(UserManager.getInstance().token))
        ) {
            mUserViewModel.retryCheckLogin()
        }
        if (busNetworkState.isNetworkConnected) {
            mHaloPersonalViewModel.getHaloAddons(false)
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(reuse: EBReuse) {
        if (MESSAGE_READ_OVER == reuse.type) { // 消息阅读完成
            mStubBinding.loginMessageHint.visibility = View.GONE
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        if (isSupportVisible) DisplayUtils.setLightStatusBar(requireActivity(), !mIsDarkModeOn)
        if (isAdded) {
            if (::mPersonalFunctionAdapter.isInitialized) mPersonalFunctionAdapter.notifyItemRangeChanged(
                0,
                mPersonalFunctionAdapter.itemCount
            )
            if (::mStubBinding.isInitialized) {
                mStubBinding.run {
                    settingItem.iconIv.setImageResource(R.drawable.ic_personal_setting)
                    feedbackItem.iconIv.setImageResource(R.drawable.ic_personal_feedback)
                    shareGhItem.iconIv.setImageResource(R.drawable.ic_personal_share)
                    userProtocolItem.iconIv.setImageResource(R.drawable.ic_personal_user_protocol)
                    privacyPolicyItem.iconIv.setImageResource(R.drawable.ic_personal_privacy_policy)
                    infoListItem.iconIv.setImageResource(R.drawable.ic_personal_info_list)
                    sdkListItem.iconIv.setImageResource(R.drawable.ic_personal_sdk)
                    permissionAndUsageItem.iconIv.setImageResource(R.drawable.ic_personal_permission)
                    childrenPolicyItem.iconIv.setImageResource(R.drawable.ic_personal_children_policy)
                    whiteBg.setBackgroundColor(R.color.background_white.toColor(requireContext()))
                    gradientBg.background = R.drawable.bg_personal_top_gradient.toDrawable(requireContext())
                    personalUserName.setTextColor(R.color.text_title.toColor(requireContext()))
                    userIdTv.setTextColor(R.color.text_subtitleDesc.toColor(requireContext()))
                    darkModeIv.setImageResource(if (mIsDarkModeOn) R.drawable.ic_personal_light_mode else R.drawable.ic_personal_dark_mode)
                    myGameTv.setTextColor(R.color.text_title.toColor(requireContext()))
                    myGameCollectionTv.setTextColor(R.color.text_title.toColor(requireContext()))
                    myCollectionTv.setTextColor(R.color.text_title.toColor(requireContext()))
                    historyTv.setTextColor(R.color.text_title.toColor(requireContext()))
                    myPostTv.setTextColor(R.color.text_title.toColor(requireContext()))
                    myGameTv.setDrawableTop(VectorDrawableCompat.create(resources, R.drawable.ic_personal_my_game, null))
                    myGameCollectionTv.setDrawableTop(VectorDrawableCompat.create(resources, R.drawable.ic_personal_my_game_collection, null))
                    myCollectionTv.setDrawableTop(VectorDrawableCompat.create(resources, R.drawable.ic_personal_my_collection, null))
                    historyTv.setDrawableTop(VectorDrawableCompat.create(resources, R.drawable.ic_personal_history, null))
                    myPostTv.setDrawableTop(VectorDrawableCompat.create(resources, R.drawable.ic_personal_my_post, null))
                }
            }
        }
    }

    companion object {
        private const val MESSAGE_READ_OVER = "MESSAGE_READ_OVER"
        private const val SP_BADGE_RECORD_SEVEN_DAY = "badgeRecordSevenDay"
        private const val REQUEST_MESSAGE = 199
        private const val MAX_RECOMMEND_COUNT = 4
        private const val MAX_MORE_FEATURES_COUNT = 12
        private const val BANNER_LOOP_TIME = 3000L
    }

    class LooperHandle(fragment: HaloPersonalFragment) : Handler(Looper.getMainLooper()) {
        private val mWeakReference: WeakReference<HaloPersonalFragment> = WeakReference(fragment)

        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            val fragment = mWeakReference.get()
            if (fragment != null && msg.what == fragment.mSlideLooperKey) {
                fragment.scrollToNextPage()
                fragment.startBannerAutoPlay()
            }
        }
    }
}