package com.gh.common.util

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import com.gh.common.constant.Config
import com.gh.gamecenter.R
import com.gh.gamecenter.ShellActivity
import com.gh.gamecenter.VerifyPhoneActivity
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.avoidcallback.AvoidOnResultManager
import com.gh.gamecenter.common.avoidcallback.Callback
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.login.user.LoginTag
import com.halo.assistant.fragment.user.UserInfoEditFragment
import com.halo.assistant.fragment.user.VerifyPhoneFragment
import com.lightgame.utils.AppManager
import com.lightgame.utils.Utils
import retrofit2.HttpException

/**
 * 这个类用来管理一些错误，像弹窗、TOAST 什么的
 */
object ErrorHelper {

    /**
     * 手动匹配处理特定错误码
     * [showHighPriorityHint] 用来标识有同样错误码可以触发两种处理时，为 true 时选择重要的
     * [customizedHandler] 返回 true 为已处理该错误码，false 则交由 [handleError] 处理
     */
    @JvmStatic
    fun handleErrorWithCustomizedHandler(
        context: Context,
        errorString: String?,
        showHighPriorityHint: Boolean = false,
        realNameConfirmListener: ConfirmListener? = null,
        customizedHandler: (code: Int) -> Boolean
    ) {
        val errorEntity = errorString?.toObject<ErrorEntity>()

        if (customizedHandler(errorEntity?.code ?: 0)) {
            return
        }

        if (errorEntity == null) {
            Utils.toast(context, R.string.post_failure_hint)
            return
        }

        if (!errorEntity.toast.isNullOrEmpty()) {
            Utils.toast(context, errorEntity.toast)
            return
        }

        handleError(context, showHighPriorityHint, errorEntity, realNameConfirmListener)
    }

    /**
     * [showHighPriorityHint] 用来标识有同样错误码可以触发两种处理时，为 true 时选择重要的
     */
    @JvmStatic
    @JvmOverloads
    fun handleError(
        context: Context,
        errorString: String?,
        showHighPriorityHint: Boolean = false,
        realNameConfirmListener: ConfirmListener? = null,
        entrance: String = ""
    ) {
        val errorEntity = errorString?.toObject<ErrorEntity>()

        if (errorEntity == null) {
            Utils.toast(context, R.string.post_failure_hint)
            return
        }

        if (!errorEntity.toast.isNullOrEmpty()) {
            Utils.toast(context, errorEntity.toast)
            return
        }

        handleError(context, showHighPriorityHint, errorEntity, realNameConfirmListener, entrance)
    }

    /***
     * 禁言错误,
     *403050： 评论回答
     *403051： 评论资讯文章
     *403055： 评论社区文章
     *403048： 发表回答
     *403053： 发表社区文章
     *403049： 发布问题
     *403046： 编辑回答
     *403045： 编辑答案
     *403057： 游戏评论
     *403054： 更新社区文章
     *403047： 回答点赞
     *403112： 发布视频贴
     *403113： 修改视频贴
     *403114： 点赞视频贴
     */
    private fun handleError(
        context: Context,
        showHighPriorityHint: Boolean = false,
        errorEntity: ErrorEntity,
        realNameConfirmListener: ConfirmListener? = null,
        entrance: String = ""
    ) {
        when (errorEntity.code) {
            403050,
            403051,
            403055,
            403048,
            403053,
            403049,
            403046,
            403045,
            403054,
            403069,
            403071,
            403047,
            403112,
            403113,
            403114 -> handleErrorWithCommunityBannedDialog(context, errorEntity)

            403057,
            403068 -> handleErrorWithCommentBannedDialog(context, errorEntity)
            403200,
            403201,
            403202 -> handleErrorWithGameCollectionBannedDialog(context, errorEntity)

            403001 -> Utils.toast(context, "标签名称太长了")
            403002 -> Utils.toast(context, "已经被邀请了")
            403003 -> Utils.toast(context, "每天最多可以邀请10次")
            403004 -> Utils.toast(context, "客户端提供的ID无效（空/无效ID）")
            403005 -> Utils.toast(context, "已经回答过了（限制频率）")
            403006 -> Utils.toast(context, "图片数量达到限制点")
            403007 -> Utils.toast(context, "不合法的用户")
            403008 -> Utils.toast(context, "已投票")
            403009 -> Utils.toast(context, "已经收藏过了")
            403010 -> Utils.toast(context, "无效的标签栏")
            403011 -> Utils.toast(context, "标题内容过长")
            403012 -> Utils.toast(context, "描述内容过长")
            403013 -> Utils.toast(context, "无效的标签")
            403014 -> Utils.toast(context, "标签数量太多了")
            403015 -> Utils.toast(context, "已经关注过了")
            404001 -> Utils.toast(context, "请求的资源不存在")
            403016 -> Utils.toast(context, "标签内容可能包含敏感信息，请修改后再提交")
            403018 -> Utils.toast(context, R.string.comment_failed_unable)
            403070 -> Utils.toast(context, "请勿重复提交~")
            403073 -> Utils.toast(context, "标题违规，请重新编辑")
            403074 -> Utils.toast(context, "该微信号（${errorEntity.data?.nickname}）已绑定")
            403078 -> Utils.toast(context, "已点赞")
            403072 -> Utils.toast(context, R.string.comment_failed_userblocked)
            403082 -> Utils.toast(context, "作者已关闭评论")
            403022 -> Utils.toast(context, "不能回复自己")
            403056 -> Utils.toast(context, "发布失败，字数已达上限")
            403111 -> Utils.toast(context, "提交失败，评论违规")
            400001 -> Utils.toast(context, "字数超过500或者未填写原因")
            403102 -> Utils.toast(context, "你已经举报过该内容了哦")
            403115 -> Utils.toast(context, "请求太频繁了,稍微休息一下")
            403119 -> Utils.toast(context, "不能重复修改实名")

            403020 -> handleAskFrequentlyError(context, showHighPriorityHint)

            403021 -> Utils.toast(context, R.string.comment_failed_illegal)

            403059 -> Utils.toast(context, "权限错误，请刷新后重试")

            400802 -> {
                // 多设备登录同一帐号，不需要这里处理
            }

            403209 -> handleRealNameError(context, errorEntity, realNameConfirmListener)

            403210 -> handleVerifyPhoneError(context, errorEntity, realNameConfirmListener, entrance)

            // 禁言（发布内容）
            403402 -> Utils.toast(context, "您的账号存在违规，不允许发布内容")
            // 禁言（点赞）
            403403 -> Utils.toast(context, "您的账号存在违规，不允许点赞")

            else -> Utils.toast(context, R.string.post_failure_hint)
        }
    }

    private fun handleAskFrequentlyError(context: Context, showHighPriorityHint: Boolean) {
        if (showHighPriorityHint) {
            DialogHelper.showDialog(
                context,
                "提醒",
                "提问过于频繁，请先休息一下哦",
                "知道了", "",
                extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
            )
        } else {
            Utils.toast(context, R.string.comment_failed_toofrequent)
        }
    }

    private fun handleRealNameError(
        context: Context,
        errorEntity: ErrorEntity,
        realNameConfirmListener: ConfirmListener?
    ) {
        DialogHelper.showDialog(
            context,
            "实名提醒",
            errorEntity.data?.title ?: "",
            "前往实名认证", "以后再说",
            uiModificationCallback = { binding ->
                binding.hintTv.visibility = View.VISIBLE
                binding.hintTv.layoutParams =
                    (binding.hintTv.layoutParams as ViewGroup.MarginLayoutParams).apply {
                        setMargins(
                            0,
                            8F.dip2px(),
                            0,
                            0
                        )
                    }
                binding.lineView.layoutParams =
                    (binding.lineView.layoutParams as ViewGroup.MarginLayoutParams).apply {
                        setMargins(
                            0,
                            23F.dip2px(),
                            0,
                            0
                        )
                    }
                binding.hintTv.text = errorEntity.data?.text
                binding.hintTv.setTextColor(R.color.theme_font.toColor(context))
                binding.hintTv.setOnClickListener {
                    errorEntity.data?.toLinkEntity()?.let { entity ->
                        DirectUtils.directToLinkPage(context, entity, "实名提醒弹窗", "")
                    }
                }
            },
            confirmClickCallback = {
                val currentActivity = AppManager.getInstance().currentActivity() ?: return@showDialog
                AvoidOnResultManager.getInstance(currentActivity as AppCompatActivity)
                    .startForResult(
                        ShellActivity.getIntent(
                            context,
                            ShellActivity.Type.REAL_NAME_INFO,
                        ), object : Callback {
                            override fun onActivityResult(resultCode: Int, data: Intent?) {
                                if (resultCode == Activity.RESULT_OK && data != null) {
                                    val isAuthSuccess =
                                        data.getBooleanExtra(UserInfoEditFragment.AUTH_SUCCESS, false)
                                    if (isAuthSuccess) {
                                        realNameConfirmListener?.onConfirm()
                                    }
                                }
                            }
                        })
            }
        )
    }

    private fun handleVerifyPhoneError(
        context: Context,
        errorEntity: ErrorEntity,
        realNameConfirmListener: ConfirmListener?,
        entrance: String
    ) {
        DialogHelper.showDialog(
            context,
            "手机号验证",
            errorEntity.data?.title ?: "",
            "前往手机号验证", "以后再说",
            uiModificationCallback = { binding ->
                binding.hintTv.visibility = View.VISIBLE
                binding.hintTv.layoutParams =
                    (binding.hintTv.layoutParams as ViewGroup.MarginLayoutParams).apply {
                        setMargins(
                            0,
                            8F.dip2px(),
                            0,
                            0
                        )
                    }
                binding.lineView.layoutParams =
                    (binding.lineView.layoutParams as ViewGroup.MarginLayoutParams).apply {
                        setMargins(
                            0,
                            23F.dip2px(),
                            0,
                            0
                        )
                    }
                binding.hintTv.text = errorEntity.data?.text
                binding.hintTv.setTextColor(R.color.theme_font.toColor(context))
                binding.hintTv.setOnClickListener {
                    errorEntity.data?.toLinkEntity()?.let { entity ->
                        DirectUtils.directToLinkPage(context, entity, "手机号验证", "")
                        NewFlatLogUtils.logPhoneNumberVerifyDialogClick(entrance, "点击了解更多")
                    }
                }
            },
            confirmClickCallback = {
                val currentActivity = AppManager.getInstance().currentActivity() ?: return@showDialog
                AvoidOnResultManager.getInstance(currentActivity as AppCompatActivity)
                    .startForResult(
                        VerifyPhoneActivity.getIntent(context), object : Callback {
                            override fun onActivityResult(resultCode: Int, data: Intent?) {
                                if (resultCode == Activity.RESULT_OK && data != null) {
                                    val isVerifySuccess =
                                        data.getBooleanExtra(VerifyPhoneFragment.VERIFY_SUCCESS, false)
                                    if (isVerifySuccess) {
                                        realNameConfirmListener?.onConfirm()
                                    }
                                }
                            }
                        })
                NewFlatLogUtils.logPhoneNumberVerifyDialogClick(entrance, "前往手机号验证")
                NewFlatLogUtils.logPhoneNumberVerifyDialogShow("手机号验证弹窗-前往验证")
            },
            cancelClickCallback = {
                NewFlatLogUtils.logPhoneNumberVerifyDialogClick(entrance, "以后再说")
            }
        )
    }

    private fun handleErrorWithGameCollectionBannedDialog(context: Context, errorEntity: ErrorEntity?) {
        val bannedType = if (errorEntity?.data?.alwaysBlock == true) {
            ""
        } else {
            "（非永久）"
        }
        val dialogContext = DialogUtils.checkDialogContext(context)
        DialogHelper.showDialog(
            dialogContext,
            "提示",
            "你因违反《游戏单管理规范》，已被禁言$bannedType，如有疑问，请联系客服（QQ：${Config.getSettings()?.support?.qq}）",
            "去看看", "关闭", {
                dialogContext.startActivity(
                    WebActivity.getWebIntent(
                        dialogContext,
                        "游戏单管理规范",
                        Constants.GAME_COLLECTION_RULE
                    )
                )
            },
            extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
        )
    }

    private fun handleErrorWithCommentBannedDialog(context: Context, errorEntity: ErrorEntity?) {
        val bannedType = if (errorEntity?.data?.alwaysBlock == true) {
            ""
        } else {
            "（非永久）"
        }
        val dialogContext = DialogUtils.checkDialogContext(context)
        DialogHelper.showDialog(
            dialogContext,
            "提示",
            "你因违反《光环助手评论规则》，已被禁言$bannedType，如有疑问，请联系客服（QQ：${Config.getSettings()?.support?.qq}）",
            "去看看", "关闭", {
                dialogContext.startActivity(
                    WebActivity.getWebIntent(
                        dialogContext,
                        dialogContext.getString(R.string.comment_rules_title),
                        dialogContext.getString(R.string.comment_rules_url)
                    )
                )
            },
            extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
        )
    }

    private fun handleErrorWithCommunityBannedDialog(context: Context, errorEntity: ErrorEntity) {
        val bannedType = if (errorEntity.data?.alwaysBlock == true) {
            ""
        } else {
            "（非永久）"
        }
        val dialogContext = DialogUtils.checkDialogContext(context)
        DialogHelper.showDialog(
            dialogContext,
            "提示",
            "你因违反《问答版块规则》，已被禁言$bannedType，如有疑问，请联系客服（QQ：${Config.getSettings()?.support?.qq}）",
            "去看看", "关闭", {
                dialogContext.startActivity(
                    WebActivity.getWebIntent(
                        dialogContext,
                        dialogContext.getString(R.string.community_rule_title),
                        dialogContext.getString(R.string.community_rule_url)
                    )
                )
            },
            extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
        )
    }

    @JvmStatic
    fun handleLoginError(
        context: Context,
        httpException: HttpException?,
        loginTagChinese: String,
        isCertificate: Boolean
    ) {
        try {
            var errorReason = ""
            val errorEntity: ErrorEntity? =
                httpException?.response()?.errorBody()?.string()?.toObject()
            when {
                errorEntity?.code == 403099 -> {
                    errorReason = "当前账号正在注销，禁止登录"
                    Utils.toast(context, errorReason)
                }

                // 用户禁止登录
                errorEntity?.code == 403401 -> {
                    errorReason = "您的账号存在违规，不允许登录"
                    Utils.toast(context, errorReason)
                }

                // 设备禁止登录
                errorEntity?.code == 403404 -> {
                    errorReason = "您的设备存在违规，不允许登录"
                    Utils.toast(context, errorReason)
                }

                errorEntity?.toast?.isNotEmpty() == true -> {
                    Utils.toast(context, errorEntity.toast)
                    errorReason = errorEntity.toast!!
                }

                else -> Utils.toast(context, R.string.login_failure)
            }
            if (!isCertificate) SensorsBridge.trackEvent(
                "LoginResult",
                "login_type",
                loginTagChinese,
                "login_result",
                "失败",
                "defeated_reason",
                errorReason
            )
        } catch (e: Exception) {
            e.printStackTrace()
            Utils.toast(context, R.string.login_failure)
        }
    }

}