package com.gh.gamecenter.common.base.fragment

import android.content.DialogInterface
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import com.gh.gamecenter.core.utils.MtaHelper
import com.lightgame.dialog.BaseDialogFragment
import java.util.concurrent.atomic.AtomicBoolean

/**
 * 对 dialog 操作进行 MTA 事件记录的 dialog fragment
 */
abstract class BaseTrackableDialogFragment : BaseDialogFragment() {

    abstract fun getEvent(): String
    abstract fun getKey(): String
    open fun getValue(): String = ""

    // 区分此 dialog 是点击 dialog 外部取消的还是点击返回取消的
    private val mIsCanceledByClickOutsideOfDialog = AtomicBoolean(true)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        if (getEvent().isEmpty()) {
            throw IllegalStateException("需要提供非空的 Event 来供 MTA 进行事件记录")
        }

        if (getKey().isEmpty()) {
            throw IllegalStateException("需要提供非空的 Key 来供 MTA 进行事件记录")
        }

        onEvent("出现弹窗")

        dialog?.setCanceledOnTouchOutside(true)
        dialog?.setOnKeyListener { _, keyCode, event ->
            if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
                mIsCanceledByClickOutsideOfDialog.set(false)
                onEvent("点击返回")
            }
            false
        }
    }

    fun onEvent(value: String) {
        if (trackWithBasicDeviceInfo()) {
            MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), value)
        } else {
            MtaHelper.onEvent(getEvent(), getKey(), value)
            if (getValue().isNotEmpty()) {
                MtaHelper.onEvent(getEvent(), value, getValue())
            }
        }
    }

    override fun onCancel(dialog: DialogInterface) {
        super.onCancel(dialog)
        if (mIsCanceledByClickOutsideOfDialog.get()) {
            onEvent("点击空白")
        }
    }

    open fun trackWithBasicDeviceInfo() = false


    override fun show(manager: FragmentManager, tag: String?) {
        val fragment = manager.findFragmentByTag(tag)
        if (fragment != null) {
            val transaction = manager.beginTransaction()
            transaction.show(fragment)
            transaction.commit()
        } else {
            try {
                val clazz: Class<*> = DialogFragment::class.java
                val dismissed = clazz.getDeclaredField("mDismissed")
                dismissed.isAccessible = true
                dismissed[this] = false
                val shownByMe = clazz.getDeclaredField("mShownByMe")
                shownByMe.isAccessible = true
                shownByMe[this] = true
                val transaction = manager.beginTransaction()
                transaction.add(this, tag)
                transaction.commitAllowingStateLoss()
            } catch (e: Exception) {
                super.show(manager, tag)
                e.printStackTrace()
            }
        }
    }
}