package com.gh.gamecenter.common.utils

import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.text.Html
import android.view.*
import androidx.annotation.DrawableRes
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.gamecenter.common.R
import com.gh.gamecenter.common.base.TrackableDialog
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.databinding.DialogAlertDefaultBinding
import com.gh.gamecenter.common.databinding.DialogGuideBinding
import com.gh.gamecenter.common.databinding.DialogProgressBinding
import com.gh.gamecenter.core.provider.ISettingProvider
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.core.utils.MtaHelper
import com.lightgame.utils.AppManager
import splitties.systemservices.layoutInflater

object DialogHelper {

    /**
     * 光环常规弹窗
     *
     * extraConfig，可选标题居中、内容居中、是否显示关闭按钮、是否显示正文辅助文本以及显示标题左侧图标等
     *
     * uiModificationCallback，可用来手动微调样式的回调，可使用 binding 来修改颜色、文字大小等
     */
    fun showDialog(
        context: Context,
        title: String,
        content: CharSequence,
        confirmText: String,
        cancelText: String,
        confirmClickCallback: (() -> Unit)? = null,
        cancelClickCallback: (() -> Unit)? = null,
        extraConfig: Config? = null,
        uiModificationCallback: ((binding: DialogAlertDefaultBinding) -> Unit)? = null,
        trackMtaEvent: Boolean = false,
        mtaEvent: String = "",
        mtaKey: String = ""
    ): Dialog? {
        val solidContext = checkDialogContext(context) ?: return null

        if (solidContext is Activity && solidContext.isFinishing) return null

        val dialog = if (trackMtaEvent) {
            TrackableDialog(solidContext, R.style.GhAlertDialog, mtaEvent, mtaKey)
        } else {
            Dialog(solidContext, R.style.GhAlertDialog)
        }

        val binding = DialogAlertDefaultBinding.inflate(LayoutInflater.from(solidContext))
        val contentView = binding.root
        binding.contentTv.text = content
        binding.titleTv.text = title

        extraConfig?.let {
            if (it.hint.isNotEmpty()) {
                binding.hintTv.visibility = View.VISIBLE
                binding.hintTv.text = it.hint
            }

            if (it.centerTitle) {
                binding.titleTv.gravity = Gravity.CENTER
            }

            if (it.centerContent) {
                binding.contentTv.gravity = Gravity.CENTER
            }

            if (it.showCloseIcon) {
                binding.closeContainer.visibility = View.VISIBLE
                binding.closeContainer.enlargeTouchArea()
                binding.closeContainer.setOnClickListener { dialog.dismiss() }
            }

            if (it.titleIcon != -1) {
                binding.titleTv.setDrawableStart(it.titleIcon)
            }
        }

        if (cancelText.isEmpty()) {
            binding.cancelTv.visibility = View.GONE
            binding.centerDivider.visibility = View.GONE
        }

        binding.cancelTv.text = cancelText
        binding.confirmTv.text = confirmText

        binding.cancelTv.setOnClickListener {
            if (trackMtaEvent) MtaHelper.onEvent(mtaEvent, mtaKey, "点击$cancelText")

            cancelClickCallback?.invoke()
            dialog.dismiss()
        }

        binding.confirmTv.setOnClickListener {
            if (trackMtaEvent) MtaHelper.onEvent(mtaEvent, mtaKey, "点击$confirmText")

            confirmClickCallback?.invoke()
            dialog.dismiss()
        }

        uiModificationCallback?.invoke(binding)

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog.setContentView(contentView)
        dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        dialog.show()

        return dialog
    }

    /**
     * 光环引导弹窗
     *
     * extraConfig，可选标题居中、内容居中、是否显示关闭按钮、是否显示正文辅助文本以及显示标题左侧图标等
     *
     * uiModificationCallback，可用来手动微调样式的回调，可使用 binding 来修改颜色、文字大小等
     */
    fun showGuideDialog(
        context: Context,
        title: String,
        content: CharSequence,
        confirmText: String,
        cancelText: String,
        confirmClickCallback: (() -> Unit)? = null,
        cancelClickCallback: (() -> Unit)? = null,
        extraConfig: Config? = null,
        uiModificationCallback: ((binding: DialogGuideBinding, dialog: Dialog) -> Unit)? = null,
        trackMtaEvent: Boolean = false,
        mtaEvent: String = "",
        mtaKey: String = ""
    ): Dialog? {
        val solidContext = checkDialogContext(context) ?: return null

        if (solidContext is Activity && solidContext.isFinishing) return null

        val dialog = if (trackMtaEvent) {
            TrackableDialog(solidContext, R.style.GhAlertDialog, mtaEvent, mtaKey)
        } else {
            Dialog(solidContext, R.style.GhAlertDialog)
        }

        val binding = DialogGuideBinding.inflate(LayoutInflater.from(solidContext))
        val contentView = binding.root
        binding.contentTv.text = content
        binding.titleTv.text = title

        extraConfig?.let {
            if (it.hint.isNotEmpty()) {
                binding.hintTv.visibility = View.VISIBLE
                binding.hintTv.text = it.hint
            }

            if (it.centerTitle) {
                binding.titleTv.gravity = Gravity.CENTER
            }

            if (it.centerContent) {
                binding.contentTv.gravity = Gravity.CENTER
            }

            if (it.showCloseIcon) {
                binding.closeContainer.visibility = View.VISIBLE
                binding.closeContainer.enlargeTouchArea()
                binding.closeContainer.setOnClickListener { dialog.dismiss() }
            }

            if (it.titleIcon != -1) {
                binding.titleTv.setDrawableStart(it.titleIcon)
            }
        }

        if (cancelText.isEmpty()) {
            binding.cancelTv.visibility = View.GONE
        }

        binding.cancelTv.text = cancelText
        binding.confirmTv.text = confirmText

        binding.cancelTv.setOnClickListener {
            if (trackMtaEvent) MtaHelper.onEvent(mtaEvent, mtaKey, "点击$cancelText")

            cancelClickCallback?.invoke()
            dialog.dismiss()
        }

        binding.confirmTv.setOnClickListener {
            if (trackMtaEvent) MtaHelper.onEvent(mtaEvent, mtaKey, "点击$confirmText")

            confirmClickCallback?.invoke()
            dialog.dismiss()
        }

        uiModificationCallback?.invoke(binding, dialog)

        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog.setContentView(contentView)
        dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        dialog.show()

        return dialog
    }

    /**
     * For legacy java invocation
     */
    @JvmStatic
    @Deprecated("Kotlin 中请使用其它方法调用")
    fun showDialog(
        context: Context,
        title: String,
        content: CharSequence,
        positiveText: String,
        negativeText: String,
        positiveClickCallback: EmptyCallback,
        negativeClickCallback: EmptyCallback,
        trackMtaEvent: Boolean = false,
        mtaEvent: String = "",
        mtaKey: String = ""
    ) {
        showDialog(
            context = context,
            title = title,
            content = content,
            confirmText = positiveText,
            cancelText = negativeText,
            confirmClickCallback = { positiveClickCallback.onCallback() },
            cancelClickCallback = { negativeClickCallback.onCallback() },
            extraConfig = Config(centerTitle = true, centerContent = true),
            trackMtaEvent = trackMtaEvent,
            mtaEvent = mtaEvent,
            mtaKey = mtaKey
        )
    }

    /**
     * For legacy java invocation
     */
    @JvmStatic
    @Deprecated("Kotlin 中请使用其它方法调用")
    fun showCenterDialog(
        context: Context,
        title: String,
        content: CharSequence,
        positiveText: String,
        negativeText: String,
        positiveClickCallback: EmptyCallback,
        negativeClickCallback: EmptyCallback
    ) {
        showDialog(
            context = context,
            title = title,
            content = content,
            confirmText = positiveText,
            cancelText = negativeText,
            confirmClickCallback = { positiveClickCallback.onCallback() },
            cancelClickCallback = { negativeClickCallback.onCallback() },
            extraConfig = Config(centerTitle = true, centerContent = true)
        )
    }

    @JvmStatic
    fun getProgressDialog(
        context: Context,
        content: String,
        uiModificationCallback: ((binding: DialogProgressBinding) -> Unit)? = null
    ): Dialog {
        val dialog = Dialog(context)
        val binding = DialogProgressBinding.inflate(context.layoutInflater)
        binding.contentTv.text = content
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(false)
        dialog.window?.setBackgroundDrawableResource(R.drawable.background_shape_white_radius_8)
        dialog.window?.attributes = dialog.window?.attributes?.apply { width = 160F.dip2px() }
        uiModificationCallback?.invoke(binding)
        dialog.show()
        return dialog
    }

    @JvmStatic
    fun showSignatureConflictDialog(
        context: Context,
        confirmClickCallback: (() -> Unit)? = null
    ) {
        showDialog(
            context,
            "温馨提示",
            "检测到安装包与已安装应用的签名不一致，需要卸载后才能安装，是否立即卸载",
            "卸载",
            "取消",
            { confirmClickCallback?.invoke() },
            null,
            Config(hint = "注意：卸载会让游戏数据丢失，请提前做好备份"),
            { binding -> binding.hintTv.setTextColor(R.color.theme_font.toColor(context)) }
        )
    }

    @JvmStatic
    fun showPluginDialog(
        context: Context,
        confirmClickCallback: (() -> Unit)? = null
    ) {
        MtaHelper.onEvent("插件化", "插件化安装弹窗", "出现弹窗提示")
        showDialog(
            context,
            "插件化安装",
            "您将进行插件化安装以实现插件功能，此过程将卸载当前使用的版本并安装插件版本",
            "确认，开始插件化",
            "取消",
            {
                confirmClickCallback?.invoke()
                MtaHelper.onEvent("插件化", "插件化安装弹窗", "确认并开始")
            },
            { MtaHelper.onEvent("插件化", "插件化安装弹窗", "取消") },
            Config(hint = "注意：卸载前请妥善保存游戏账号与密码"),
            { binding -> binding.hintTv.setTextColor(R.color.text_FF0000.toColor()) }
        )
    }

    @JvmStatic
    fun showUpgradeDialog(context: Context) {
        showDialog(
            context,
            "提示",
            "当前版本暂不支持该功能，\n建议您升级到最新版本体验哦",
            "检查升级",
            "取消",
            confirmClickCallback = {
                val settingProvider =
                    ARouter.getInstance().build(RouteConsts.provider.setting).navigation() as? ISettingProvider
                context.startActivity(settingProvider?.getAboutIntent(context, true))
            },
            uiModificationCallback = {
                it.titleTv.gravity = Gravity.CENTER
                it.contentTv.gravity = Gravity.CENTER
            }
        )
    }


    @JvmStatic
    fun showDowngradeHintDialog(
        context: Context,
        confirmClickCallback: (() -> Unit)? = null
    ) {
        showDialog(
            context,
            "温馨提示",
            "您已安装较高版本，若要安装历史版本需先卸载再安装\n",
            "我知道了",
            "",
            { confirmClickCallback?.invoke() })
    }

    @JvmStatic
    fun showCenterWarningDialog(
        context: Context,
        title: String,
        msg: CharSequence,
        confirmClickCallback: EmptyCallback
    ) {
        showCenterWarningDialog(
            context = context,
            title = title,
            msg = msg,
            confirmClickCallback = { confirmClickCallback.onCallback() },
            cancelClickCallback = null,
        )
    }

    @JvmStatic
    fun showWarningDialog(
        context: Context,
        title: String,
        msg: CharSequence,
        cancelText: String = "取消",
        confirmText: String = "确定",
        confirmClickCallback: (() -> Unit)? = null,
        cancelClickCallback: (() -> Unit)? = null
    ) {
        showDialog(
            context,
            title,
            msg,
            confirmText,
            cancelText,
            confirmClickCallback,
            cancelClickCallback
        )
    }

    @JvmStatic
    fun showCenterWarningDialog(
        context: Context,
        title: String,
        msg: CharSequence,
        cancelText: String = "取消",
        confirmText: String = "确定",
        confirmClickCallback: (() -> Unit)? = null,
        cancelClickCallback: (() -> Unit)? = null
    ) {
        showDialog(
            context,
            title,
            msg,
            confirmText,
            cancelText,
            confirmClickCallback,
            cancelClickCallback,
            extraConfig = Config(centerContent = true, centerTitle = true)
        )
    }

    @JvmStatic
    fun showDownloadDialog(context: Context, listener: ConfirmListener) {
        showCenterWarningDialog(
            context,
            "下载提示",
            "您当前使用的网络为2G/3G/4G，开始下载将会消耗移动流量，确定下载？",
            confirmClickCallback = { listener.onConfirm() }
        )
    }

    @JvmStatic
    fun showCancelDialog(
        context: Context,
        confirmClickCallback: (() -> Unit)? = null,
        cancelClickCallback: (() -> Unit)? = null
    ) {
        val content = Html.fromHtml(context.getString(R.string.cancel_concern_dialog))
        showDialog(
            context,
            "取消关注",
            content,
            "确定取消",
            "暂不取消",
            confirmClickCallback,
            cancelClickCallback,
            extraConfig = Config(centerTitle = true, centerContent = true)
        )
    }

    @JvmStatic
    fun showDialogWithHtmlContent(
        context: Context,
        title: String,
        content: String,
        confirmText: String,
        cancelText: String,
        confirmClickCallback: (() -> Unit)? = null,
        cancelClickCallback: (() -> Unit)? = null
    ) {
        val webContent = Html.fromHtml(content)
        showDialog(
            context,
            title,
            webContent,
            confirmText,
            cancelText,
            confirmClickCallback,
            cancelClickCallback
        )
    }

    fun showDeleteGameCommentDialog(
        context: Context,
        content: String,
        confirmClickCallback: (() -> Unit)
    ) {
        showDialog(
            context,
            "提示",
            content,
            "删除",
            "取消",
            confirmClickCallback,
            extraConfig = Config(centerTitle = true, centerContent = true)
        )
    }

    @JvmStatic
    fun showLibaoActivityDialog(
        context: Context,
        isHideHint: Boolean,
        hintClickCallback: EmptyCallback
    ) {
        showDialog(
            context,
            "查看礼包码",
            "游戏礼包可通过参与活动获取",
            "我知道了",
            "",
            extraConfig = Config(centerTitle = true),
            uiModificationCallback = { binding ->
                binding.hintTv.run {
                    if (isHideHint) {
                        visibility = View.GONE
                    } else {
                        visibility = View.VISIBLE
                        text = "查看活动详情"
                        setTextColor(R.color.theme_font.toColor(context))
                        setDrawableEnd(R.drawable.ic_libao_activity_arrow)
                        compoundDrawablePadding = 4F.dip2px()
                        setOnClickListener {
                            hintClickCallback.onCallback()
                        }
                    }
                }

                binding.lineView.visibility = View.GONE

                binding.confirmTv.run {
                    layoutParams = (layoutParams as ViewGroup.MarginLayoutParams).apply {
                        leftMargin = 24F.dip2px()
                        topMargin = 24F.dip2px()
                        rightMargin = 24F.dip2px()
                        bottomMargin = 26F.dip2px()
                    }
                    setBackgroundResource(R.drawable.button_blue_oval)
                    setTextColor(R.color.text_white.toColor(context))
                }
            }
        )
    }

    @JvmStatic
    fun showDeleteDialog(
        context: Context,
        title: String,
        msg: CharSequence,
        confirmText: String,
        cancelText: String,
        confirmClickCallback: EmptyCallback?,
        cancelClickCallback: EmptyCallback?,
        isReverse: Boolean
    ) {
        showDialog(
            context,
            title,
            msg,
            if (isReverse) cancelText else confirmText,
            if (isReverse) confirmText else cancelText,
            confirmClickCallback = {
                if (isReverse) cancelClickCallback?.onCallback() else confirmClickCallback?.onCallback()
            },
            cancelClickCallback = {
                if (isReverse) confirmClickCallback?.onCallback() else cancelClickCallback?.onCallback()
            },
            uiModificationCallback = {
                val colorAccentRes = if (isReverse) R.color.theme_red else R.color.text_subtitle
                val colorDefaultRes = if (isReverse) R.color.text_subtitle else R.color.theme_red
                it.cancelTv.setTextColor(colorAccentRes.toColor(context))
                it.confirmTv.setTextColor(colorDefaultRes.toColor(context))
            },
            extraConfig = Config(centerTitle = true, centerContent = true)
        )?.setOnCancelListener {
            cancelClickCallback?.onCallback()
        }
    }

    /**
     * @param context may be is application context
     * @return activity context
     */
    private fun checkDialogContext(context: Context?): Context? {
        if (context == null) {
            throw NullPointerException("dialog context is null")
        }
        return context as? Activity ?: AppManager.getInstance().currentActivity()

        // currentActivity 是否存在 isDestroyed 的情况?
    }

    data class Config(
        val hint: String = "",
        val showCloseIcon: Boolean = false,
        val centerTitle: Boolean = false,
        val centerContent: Boolean = false,
        @DrawableRes
        val titleIcon: Int = -1
    )

}