package com.gh.vspace

import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.gh.common.exposure.ExposureUtils
import com.gh.common.exposure.ExposureUtils.DownloadType.DOWNLOAD
import com.gh.common.exposure.ExposureUtils.DownloadType.UPDATE
import com.gh.common.util.*
import com.gh.common.util.NewFlatLogUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.base.fragment.BaseDraggableDialogFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.DialogVspace32NewBinding
import com.gh.gamecenter.entity.AppEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.view.DownloadButton
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadConfig
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus.*
import com.lightgame.utils.AppManager
import java.io.File

class VSpace32NewDialogFragment : BaseDraggableDialogFragment() {

    private var mAppEntity: AppEntity? = null
    private var mGameId: String = ""
    private var mGameName: String = ""
    private val mDownloadUrl by lazy { mAppEntity?.url ?: "" }
    private val mBinding by lazy { DialogVspace32NewBinding.inflate(layoutInflater) }
    private var mIsLogInstallShow = false
    private var mIsLogAutoInstallClick = false
    private var mIsClickDownloadThisTime = false // 是否本次弹出Dialog点击的下载按钮
    private val mDataWatcher = object : DataWatcher() {
        override fun onDataChanged(downloadEntity: DownloadEntity) {
            if (downloadEntity.url == mDownloadUrl && isAdded) {
                updateDownloadButton(downloadEntity)
            }
        }

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

    override fun getRootView(): View = mBinding.root
    override fun getDragCloseView(): View = mBinding.dragClose

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        mAppEntity = arguments?.get(KEY_APP_ENTITY_32) as AppEntity
        mGameId = arguments?.getString(EntranceConsts.KEY_GAME_ID) ?: ""
        mGameName = arguments?.getString(EntranceConsts.KEY_GAME_NAME) ?: ""
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return mBinding.root
    }

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

        val mViewModel = viewModelProvider<VSpaceDialogFragment.VSpaceDialogViewModel>()
        mViewModel.packageLiveData.observe(this) {
            if (it.packageName == VHelper.VSPACE_32BIT_NEW_PACKAGENAME) {
                dismissAllowingStateLoss()
            }
        }

        val downloadSnapshot = DownloadManager.getInstance()
            .getDownloadEntitySnapshotByPackageName(VHelper.VSPACE_32BIT_NEW_PACKAGENAME)
        mBinding.downloadBtn.text = if (downloadSnapshot?.status == done) "安装" else "下载"
        mBinding.downloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
        mBinding.descTv.text = "《$mGameName》需安装完整的畅玩服务组件，安装后即可给您带来急速的畅玩体验~"
        mBinding.privacyPolicyTv.setOnClickListener {
            NewFlatLogUtils.logHaloFunEvent("halo_fun_download_dialog_privacy_click")
            DirectUtils.directToWebView(requireContext(), Constants.SMOOTH_GAME_PRIVACY_POLICY_ADDRESS)
        }

        if (downloadSnapshot?.status == done) {
            NewFlatLogUtils.logHaloFunEvent("halo_fun_32_install_tip_dialog_show")
            SensorsBridge.trackEvent("HaloFunExpandInstallDialogShow")
            mIsLogInstallShow = true
        } else {
            NewFlatLogUtils.logHaloFun32DialogEvent("halo_fun_32_download_tip_dialog_show", mGameId, mGameName)
            SensorsBridge.trackEvent("HaloFunExpandDownloadDialogShow", "game_id", mGameId, "game_name", mGameName)
        }

        mBinding.downloadBtn.setOnClickListener {
            if (downloadSnapshot?.status == done) {
                if (!File(downloadSnapshot.path).exists()) {
                    ToastUtils.toast("畅玩组件已损坏，即将重新下载")
                    DownloadManager.getInstance().cancel(downloadSnapshot.url)
                    DownloadManager.getInstance().add(downloadSnapshot)
                } else {
                    PackageInstaller.install(requireContext(), downloadSnapshot)
                    NewFlatLogUtils.logHaloFunEvent("halo_fun_32_install_tip_dialog_click")
                    SensorsBridge.trackEvent("HaloFunExpandInstallButtonClick")
                }
            } else {
                val downloadEntity = DownloadEntity()

                val name = "畅玩游戏助手V" + mAppEntity?.version
                val downloadId = PackageInstaller.createDownloadId(name)

                downloadEntity.url = mDownloadUrl
                downloadEntity.name = name
                downloadEntity.platform = "官方版"
                downloadEntity.gameId = Constants.HALO_FUN_NEW_32_GAME_ID
                downloadEntity.path = PackageInstaller.getDownloadPathWithId(downloadId, "apk")
                downloadEntity.packageName = VHelper.VSPACE_32BIT_NEW_PACKAGENAME
                downloadEntity.addMetaExtra(DownloadConfig.KEY_PROGRESS_CALLBACK_INTERVAL, "200")

                val gameEntity = GameEntity(downloadEntity.gameId, downloadEntity.name)
                gameEntity.gameVersion = mAppEntity?.version ?: ""

                // 确定下载类型
                val downloadType =
                    if (arguments?.getBoolean(VSpaceDialogFragment.KEY_IS_UPDATE) == true) UPDATE else DOWNLOAD

                downloadEntity.exposureTrace = ExposureUtils.logADownloadExposureEvent(
                    gameEntity,
                    downloadEntity.platform,
                    null,
                    downloadType
                ).toJson()

                mIsClickDownloadThisTime = true

                AppExecutor.uiExecutor.executeWithDelay({
                    DownloadManager.getInstance().cancel(mDownloadUrl)
                    DownloadManager.getInstance().add(downloadEntity)
                }, 200)

                DataCollectionUtils.uploadDownload(HaloApp.getInstance(), downloadEntity, "开始")
                NewFlatLogUtils.logHaloFun32DialogEvent("halo_fun_32_download_tip_dialog_click", mGameId, mGameName)
                SensorsBridge.trackEvent("HaloFunExpandDownloadDialogDownloadClick")
            }
        }

    }

    override fun onStart() {
        super.onStart()
        DownloadManager.getInstance().addObserver(mDataWatcher)

        // 上面监听安装包名变化的 LiveData 监听有可能被冲掉了
        // 手动再检查一下安装状态，避免出现已安装但是没有 dismiss 弹窗的问题
        if (PackageUtils.isInstalledFromAllPackage(requireContext(), VHelper.VSPACE_32BIT_NEW_PACKAGENAME)) {
            dismissAllowingStateLoss()
        }
    }

    override fun onStop() {
        super.onStop()
        DownloadManager.getInstance().removeObserver(mDataWatcher)
    }

    private fun updateDownloadButton(downloadEntity: DownloadEntity) {
        val downloadBtn = mBinding.downloadBtn
        downloadBtn.progress = (downloadEntity.progress * 10).toInt()
        when (downloadEntity.status) {
            downloading -> {
                downloadBtn.setText(com.gh.gamecenter.feature.R.string.pause)
                downloadBtn.progress = (downloadEntity.percent * 10).toInt()
                downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
                downloadBtn.setOnClickListener {
                    DownloadManager.getInstance().pause(mDownloadUrl)
                }
            }

            pause -> {
                downloadBtn.setText(com.gh.gamecenter.feature.R.string.resume)
                downloadBtn.setOnClickListener {
                    DownloadManager.getInstance().resume(downloadEntity, true)
                }
            }

            overflow,
            timeout,
            neterror,
            diskisfull,
            waiting,
            subscribe -> {
                downloadBtn.setText(com.gh.gamecenter.feature.R.string.waiting)
                downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
                downloadBtn.setOnClickListener {
                    DownloadManager.getInstance().resume(downloadEntity, false)
                }
            }

            done -> {
                downloadBtn.setText(com.gh.gamecenter.feature.R.string.install)
                downloadBtn.buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL

                if (!mIsLogInstallShow) {
                    NewFlatLogUtils.logHaloFunEvent("halo_fun_32_install_tip_dialog_show")
                    NewFlatLogUtils.logHaloFunInstallTipDialogShow("32位")
                    SensorsBridge.trackEvent("HaloFunExpandInstallDialogShow")
                    mIsLogInstallShow = true
                }

                val isVSpace32DownloadOnly =
                    downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.VSPACE_32_DOWNLOAD_ONLY
                val isAutoInstall = SPUtils.getBoolean(Constants.SP_AUTO_INSTALL, true)
                if (!isVSpace32DownloadOnly && isAutoInstall && !mIsLogAutoInstallClick && mIsClickDownloadThisTime) {
                    NewFlatLogUtils.logHaloFunEvent("halo_fun_32_install_tip_dialog_click")
                    SensorsBridge.trackEvent("HaloFunExpandInstallButtonClick")
                    mIsLogAutoInstallClick = true
                }

                downloadBtn.setOnClickListener {
                    if (!File(downloadEntity.path).exists()) {
                        ToastUtils.toast("畅玩组件已损坏，即将重新下载")
                        DownloadManager.getInstance().cancel(downloadEntity.url)
                        DownloadManager.getInstance().add(downloadEntity)
                    } else {
                        PackageInstaller.install(requireContext(), downloadEntity)
                        NewFlatLogUtils.logHaloFunEvent("halo_fun_32_install_tip_dialog_click")
                        SensorsBridge.trackEvent("HaloFunExpandInstallButtonClick")
                    }
                }
            }

            cancel,
            hijack,
            notfound,
            uncertificated,
            unqualified -> {
                downloadBtn.text = "下载"
                downloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
                downloadBtn.setOnClickListener {
                    DownloadManager.getInstance().resume(downloadEntity, true)
                }
            }

            else -> {
                // do nothing
            }
        }
    }

    companion object {
        const val KEY_APP_ENTITY_32 = "app_entity_32"

        @JvmStatic
        fun showDownloadDialog(
            context: Context?,
            appEntity32: AppEntity,
            gameId: String = "",
            gameName: String = ""
        ) {
            val fragmentActivity: FragmentActivity = if (context is FragmentActivity) {
                context
            } else {
                val currentActivity = AppManager.getInstance().currentActivity()
                if (currentActivity is FragmentActivity) {
                    currentActivity
                } else {
                    throw IllegalStateException("current activity context must be FragmentActivity")
                }
            }

            // 防止重复弹出
            if (hasDialogDisplayedInCurrentActivity(fragmentActivity)) return

            val downloadDialog = VSpace32NewDialogFragment().apply {
                arguments = Bundle().apply {
                    putParcelable(KEY_APP_ENTITY_32, appEntity32)
                    putString(EntranceConsts.KEY_GAME_ID, gameId)
                    putString(EntranceConsts.KEY_GAME_NAME, gameName)
                }
            }
            downloadDialog.show(
                fragmentActivity.supportFragmentManager,
                VSpace32NewDialogFragment::class.java.name
            )
        }

        private fun hasDialogDisplayedInCurrentActivity(fragmentActivity: FragmentActivity): Boolean {
            val fragments: List<Fragment> = fragmentActivity.supportFragmentManager.fragments
            fragments.forEach { fragment ->
                if (fragment is VSpace32NewDialogFragment) return true
            }
            return false
        }
    }
}