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.DataCollectionUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.PackageInstaller
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.BaseActivity
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.databinding.DialogVspace32Binding
import com.gh.gamecenter.entity.AppEntity
import com.gh.gamecenter.feature.entity.GameEntity
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

class VSpace32DialogFragment : 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 { DialogVspace32Binding.inflate(layoutInflater) }
    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_PACKAGENAME) {
                dismissAllowingStateLoss()
            }
        }

        val downloadSnapshot = DownloadManager.getInstance()
            .getDownloadEntitySnapshotByPackageName(VHelper.VSPACE_32BIT_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)
        }


        mBinding.downloadBtn.setOnClickListener {
            if (downloadSnapshot?.status == done) {
                PackageInstaller.install(requireContext(), downloadSnapshot)
                SensorsBridge.trackEvent("HaloFunInstallButtonClick")
            } else {
                val downloadEntity = DownloadEntity()

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

                downloadEntity.url = mDownloadUrl
                downloadEntity.name = name
                downloadEntity.platform = "官方版"
                downloadEntity.gameId = "62bd412bbbf04747cd3de539"
                downloadEntity.path = PackageInstaller.getDownloadPathWithId(downloadId, "apk")
                downloadEntity.packageName = VHelper.VSPACE_32BIT_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()

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

                DataCollectionUtils.uploadDownload(HaloApp.getInstance(), downloadEntity, "开始")
            }
        }

    }

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

        // 上面监听安装包名变化的 LiveData 监听有可能被冲掉了
        // 手动再检查一下安装状态，避免出现已安装但是没有 dismiss 弹窗的问题
        if (PackageUtils.isInstalled(requireContext(), VHelper.VSPACE_32BIT_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(R.string.pause)
                downloadBtn.progress = (downloadEntity.percent * 10).toInt()
                downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
                downloadBtn.setOnClickListener {
                    DownloadManager.getInstance().pause(mDownloadUrl)
                }
            }

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

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

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

                SensorsBridge.trackEvent("HaloFunDownloadDone")

                downloadBtn.setOnClickListener {
                    PackageInstaller.install(requireContext(), downloadEntity)
                    SensorsBridge.trackEvent("HaloFunInstallButtonClick")
                }
            }

            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"
        const val KEY_AUTO_DOWNLOAD = "auto_download"
        const val KEY_IS_UPDATE = "is_update"

        @JvmStatic
        fun showDownloadDialog(
            context: Context?,
            appEntity32: AppEntity,
            autoDownload: Boolean = false,
            isUpdate: Boolean = false,
            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

            NewFlatLogUtils.logHaloFunEvent("halo_fun_download_dialog_show")

            if (context is BaseActivity) {
                SensorsBridge.trackEvent(
                    "HaloFunDownloadDialogShow",
                    "last_page_name", context::class.java.simpleName,
                    "last_page_id", context.getUniqueId(),
                    "last_page_business_id", context.getBusinessId().first,
                )
            }


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

        @JvmStatic
        fun showDownloadDialog(
            context: Context?,
            appEntity32: AppEntity,
            gameEntity: GameEntity?,
            autoDownload: Boolean = false,
            isUpdate: Boolean = false
        ) {
            showDownloadDialog(
                context,
                appEntity32,
                autoDownload,
                isUpdate,
                gameEntity?.id ?: "",
                gameEntity?.name ?: ""
            )
        }

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