package com.gh.gamecenter.cloudarchive

import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.MenuItem
import android.view.Window
import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.BaseActivity_TabLayout
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.ActivityCloudArchiveManagerBinding
import com.gh.gamecenter.databinding.DialogUploadArchiveBinding
import com.gh.gamecenter.entity.ArchiveEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.gamecenter.livedata.EventObserver
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.va.VCore
import com.gh.gamecenter.va.provider.IVa
import com.gh.vspace.VArchiveHelper
import com.gh.vspace.VHelper
import com.gh.vspace.VHelper.is32
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.utils.Utils
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.File

/**
 * 云存档管理
 */
class CloudArchiveManagerActivity : BaseActivity_TabLayout(), ArchiveLimitSelectedListener {

    private lateinit var mBinding: ActivityCloudArchiveManagerBinding
    private var mGameEntity: GameEntity? = null
    private var mArchiveConfigUrl = ""
    private var mArchiveFragment: MyArchiveFragment? = null
    private var mDownloadArchiveFragment: MyDownloadArchiveFragment? = null
    private var mShareArchiveFragment: MyShareArchiveFragment? = null
    private val mViewModel: CloudArchiveManagerViewModel by lazy {
        viewModelProviderFromParent(
            CloudArchiveManagerViewModel.Factory(
                gameId = mGameEntity?.id ?: "",
                gameName = mGameEntity?.name ?: "",
                configUrl = mArchiveConfigUrl
            )
        )
    }

    private val va: IVa by lazy { VCore.getInstance() }

    private val dataWatcher = object : DataWatcher() {
        override fun onDataChanged(downloadEntity: DownloadEntity) {
            if (downloadEntity.gameId == mViewModel.gameId && mGameEntity?.getApk()?.size == 1) {
                updateDownloadBtn(downloadEntity, mBinding.downloadBtn, mGameEntity)
            }
        }

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

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

        // 重连服务
        VHelper.reconnectServiceIfNeeded()

        mGameEntity = intent.getParcelableExtra<GameEntity?>(EntranceConsts.KEY_GAME)?.apply {
            setEntryMap(DownloadManager.getInstance().getEntryMap(name))
        }
        mArchiveConfigUrl = intent.getStringExtra(EntranceConsts.KEY_ARCHIVE_CONFIG_URL) ?: ""
        mBinding = ActivityCloudArchiveManagerBinding.bind(mContentView)
        setNavigationTitle("云存档")
        setToolbarMenu(R.menu.menu_cloud_archive_manager)
        updateStatusBarColor(com.gh.gamecenter.common.R.color.ui_surface, com.gh.gamecenter.common.R.color.ui_surface)
        NewFlatLogUtils.logCloudArchiveManagePageShow(mGameEntity?.id ?: "", mGameEntity?.name ?: "", mEntrance)
        SensorsBridge.trackEvent(
            "CloudSaveManagePageShow",
            "game_id", mGameEntity?.id ?: "",
            "game_name", mGameEntity?.name ?: "",
            "source_entrance", mEntrance
        )

        mBinding.run {
            mGameEntity?.let {
                gameIconView.displayGameIcon(it)
                gameNameTv.text = it.name
            }
            controlUploadGameArchive()
            uploadTv.setOnClickListener {
                when {
                    mGameEntity.is32() && VHelper.isInnerInstalled(mGameEntity?.getUniquePackageName()) && !va.isExtPackageInstalled() -> {
                        VHelper.newCwValidateVspaceBeforeAction(this@CloudArchiveManagerActivity, mGameEntity) {
                        }
                    }
                    // 检查是否已安装游戏
                    !VHelper.isInstalled(mGameEntity?.getUniquePackageName()) -> toast("暂未检测到本地的存档数据，请玩会儿游戏再试~")
                    else -> {
                        mViewModel.getArchiveConfigString {
                            // 检查本地是否存在存档数据
                            if (!VHelper.checkArchiveExist(mGameEntity?.getUniquePackageName() ?: "", it)) {
                                toast("暂未检测到本地的存档数据，请玩会儿游戏再试~")
                            } else {
                                NewFlatLogUtils.logCloudArchiveUploadDialogShow(
                                    mGameEntity?.id ?: "",
                                    mGameEntity?.name ?: ""
                                )
                                SensorsBridge.trackEvent(
                                    "CloudSaveUploadDialogShow",
                                    "game_id", mGameEntity?.id ?: "",
                                    "game_name", mGameEntity?.name ?: ""
                                )

                                mViewModel.checkLimitReachedBeforeSave()
                            }
                        }
                    }
                }
            }
        }

        mViewModel.uploadSuccess.observeNonNull(this) {
            if (it) {
                mArchiveFragment?.onLoadRefresh()
                toast("上传成功")
            } else {
                toast("上传失败")
            }
        }

        mViewModel.gameEntityLiveData.observeNonNull(this) {
            mGameEntity = it
            initDownloadBtn()
        }

        mViewModel.uploadArchiveAction.observe(this, EventObserver {
            mViewModel.getArchiveConfigString { showUploadDialog(it, null) }
        })

        mViewModel.showArchiveLimitAction.observe(this, EventObserver {
            ArchiveLimitDialogFragment.show(supportFragmentManager, it.toArrayList())
        })
    }

    override fun onMenuItemClick(item: MenuItem?): Boolean {
        if (item?.itemId == R.id.menu_help) {
            if (EnvHelper.isDevEnv) {
                DirectUtils.directToArticle(this, DEV_HELP_ARTICLE_ID, "云存档管理")
            } else {
                DirectUtils.directToArticle(this, HELP_ARTICLE_ID, "云存档管理")
            }
            return true
        }
        return super.onMenuItemClick(item)
    }

    override fun getLayoutId(): Int = R.layout.activity_cloud_archive_manager

    override fun initFragmentList(fragments: MutableList<Fragment>) {
        fragments.add(MyArchiveFragment().apply { mArchiveFragment = this }.with(intent.extras))
        fragments.add(MyDownloadArchiveFragment().apply { mDownloadArchiveFragment = this }.with(intent.extras))
        fragments.add(MyShareArchiveFragment().apply { mShareArchiveFragment = this }.with(intent.extras))
    }

    override fun initTabTitleList(tabTitleList: MutableList<String>) {
        tabTitleList.add("我的存档")
        tabTitleList.add("我的下载")
        tabTitleList.add("我的分享")
    }

    override fun onPageSelected(position: Int) {
        super.onPageSelected(position)
        mCheckedIndex = position
        NewFlatLogUtils.logCloudArchiveTabShow(
            mGameEntity?.id ?: "",
            mGameEntity?.name ?: "",
            if (position == MY_ARCHIVE_INDEX) "我的存档" else if (position == MY_DOWNLOAD_ARCHIVE_INDEX) "我的下载" else "我的分享"
        )
        SensorsBridge.trackEvent(
            "CloudSaveManagePageTabSelected",
            "game_id",
            mGameEntity?.id ?: "",
            "game_name",
            mGameEntity?.name ?: "",
            "tab_name",
            if (position == MY_ARCHIVE_INDEX) "我的存档" else if (position == MY_DOWNLOAD_ARCHIVE_INDEX) "我的下载" else "我的分享"
        )
        controlUploadGameArchive()
    }

    override fun onResume() {
        super.onResume()
        initDownloadBtn()
        DownloadManager.getInstance().addObserver(dataWatcher)
    }

    private fun initDownloadBtn() {
        mGameEntity?.let { gameEntity ->
            DownloadItemUtils.updateDownloadButton(this, mBinding.downloadBtn, gameEntity, listener = null)
            DownloadItemUtils.setOnClickListener(this, mBinding.downloadBtn, gameEntity, 0, null, mEntrance, "")
        }
    }

    override fun onPause() {
        super.onPause()
        DownloadManager.getInstance().removeObserver(dataWatcher)
    }

    fun controlUploadGameArchive() {
        val shouldShowUploadGameArchive =
            (mCheckedIndex == MY_ARCHIVE_INDEX) || (mCheckedIndex == MY_DOWNLOAD_ARCHIVE_INDEX && mDownloadArchiveFragment?.isEmpty == true)
        showUploadGameArchive(shouldShowUploadGameArchive)
    }

    private fun showUploadGameArchive(show: Boolean) {
        mBinding.uploadContainer.goneIf(!show || !CheckLoginUtils.isLogin())
        mBinding.divider.goneIf(!show || !CheckLoginUtils.isLogin())
    }

    private fun showUploadDialog(config: String, archive: ArchiveEntity?) {
        val dialog = Dialog(this)
        val binding = DialogUploadArchiveBinding.inflate(layoutInflater)
        binding.run {
            clearIv.setOnClickListener {
                contentEt.text.clear()
            }
            contentEt.doOnTextChanged { text, _, _, _ ->
                clearIv.goneIf(text?.length == 0)
                confirmTv.isEnabled = text?.length != 0
                confirmTv.alpha = if (text?.length != 0) 1F else 0.4F
            }
            confirmTv.setOnClickListener {
                SensorsBridge.trackEvent(
                    "CloudSaveUploadDialogClick",
                    "game_id", mGameEntity?.id ?: "",
                    "game_name", mGameEntity?.name ?: "",
                    "button_name", "确定"
                )
                if (contentEt.text.trim().length in 3..30) {
                    saveAndUploadArchive(contentEt.text.toString().trim(), config, archive?.id ?: "")
                    dialog.dismiss()
                } else {
                    toast("存档名称限制3~30个字符")
                }
            }
            cancelTv.setOnClickListener {
                SensorsBridge.trackEvent(
                    "CloudSaveUploadDialogClick",
                    "game_id", mGameEntity?.id ?: "",
                    "game_name", mGameEntity?.name ?: "",
                    "button_name", "取消"
                )
                dialog.dismiss()
            }
        }
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(true)
        dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        dialog.show()
    }

    private fun saveAndUploadArchive(archiveName: String, config: String, archiveId: String = "") {
        val pathName = "${VArchiveHelper.archivePath}${
            MD5Utils.getContentMD5(
                System.currentTimeMillis().toString()
            )
        }.zip"
        VArchiveHelper.saveGameArchive(
            this@CloudArchiveManagerActivity,
            mGameEntity?.getUniquePackageName() ?: "",
            config,
            File(pathName)
        ) { entity ->
            OssUploadUtils.uploadFile(
                pathName,
                OssUploadUtils.UploadType.GAME_ARCHIVE,
                object : OssUploadUtils.OnUploadFileListener {
                    override fun onSuccess(url: String) {
                        val archiveEntity = ArchiveEntity(
                            name = archiveName,
                            url = url,
                            configUrl = mArchiveConfigUrl,
                            md5 = entity.md5,
                            gameVersion = entity.gameVersion
                        )
                        if (archiveId.isBlank()) {
                            mViewModel.postArchive(archiveEntity)
                        } else {
                            mViewModel.replaceArchive(archiveEntity, archiveId)
                        }

                    }

                    override fun onError(e: Throwable?) {
                        toast("存档上传失败")
                    }
                },
                mGameEntity?.id ?: "",
                entity.md5
            )
        }
    }

    private fun updateDownloadBtn(
        downloadEntity: DownloadEntity?, downloadBtn: DownloadButton, gameEntity: GameEntity?
    ) {
        // 青少年模式显示查看
        if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
            downloadBtn.text = "查看"
            downloadBtn.buttonStyle = DownloadButton.ButtonStyle.TEENAGER_MODE
            return
        }

        if (downloadEntity != null) {
            val status = downloadEntity.status
            var btnText = getString(com.gh.gamecenter.feature.R.string.downloading)
            var backgroundType = DownloadButton.ButtonStyle.NORMAL

            downloadBtn.apply {
                when (status) {
                    DownloadStatus.downloading -> {
                        btnText = "${downloadEntity.percent}%"
                        backgroundType = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
                        progress = (downloadEntity.percent * 10).toInt()
                        setOnClickListener {
                            DownloadManager.getInstance().pause(downloadEntity.url)
                        }
                    }
                    DownloadStatus.waiting -> {
                        btnText = getString(com.gh.gamecenter.feature.R.string.waiting)
                        setOnClickListener { Utils.toast(this@CloudArchiveManagerActivity, "最多只能同时下载三个任务，请稍等"); }
                    }
                    DownloadStatus.pause, DownloadStatus.timeout, DownloadStatus.neterror, DownloadStatus.subscribe, DownloadStatus.overflow -> {
                        btnText = getString(com.gh.gamecenter.feature.R.string.resume)
                        setOnClickListener {
                            DownloadManager.getInstance().resume(downloadEntity, false)
                        }
                    }
                    DownloadStatus.done -> {
                        if (PackagesManager.isCanUpdate(
                                gameEntity?.id,
                                gameEntity?.getApk()?.firstOrNull()?.packageName,
                                true
                            )
                        ) {
                            btnText = getString(com.gh.gamecenter.feature.R.string.update)
                            setOnClickListener {
                                PackagesManager.getUpdateList().firstOrNull { it.id == downloadEntity.gameId }?.let {
                                    VHelper.updateOrReDownload(downloadEntity, it)
                                }
                            }
                        } else {
                            btnText = getString(com.gh.gamecenter.feature.R.string.launch)
                            setOnClickListener {
                                CurrentActivityHolder.getCurrentActivity()?.let {
                                    VHelper.installOrLaunch(it, downloadEntity)
                                }
                            }
                        }
                    }
                    else -> {
                        // do nothing
                    }
                }

                text = btnText
                buttonStyle = backgroundType
            }
        } else {
            downloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
            downloadBtn.text = "畅玩"
        }
    }

    override fun onDarkModeChanged() {
        super.onDarkModeChanged()
        updateStatusBarColor(com.gh.gamecenter.common.R.color.ui_surface, com.gh.gamecenter.common.R.color.ui_surface)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMainThread(reuse: EBReuse) {
        when (reuse.type) {
            Constants.LOGIN_TAG -> {
                controlUploadGameArchive()
            }
            "download" -> {
                mBinding.downloadBtn.performClick()
            }
        }
    }

    fun updateMyArchive() {
        mArchiveFragment?.onLoadRefresh()
    }

    fun updateMyDownloadArchive() {
        mDownloadArchiveFragment?.onLoadRefresh()
    }

    fun updateMyShareArchive() {
        mShareArchiveFragment?.onLoadRefresh()
    }

    override fun onSelected(archive: ArchiveEntity) {
        mViewModel.getArchiveConfigString { showUploadDialog(it, archive) }
    }

    companion object {
        const val MY_ARCHIVE_INDEX = 0
        const val MY_DOWNLOAD_ARCHIVE_INDEX = 1
        const val MY_SHARE_ARCHIVE_INDEX = 2

        private const val DEV_HELP_ARTICLE_ID = "173387"
        private const val HELP_ARTICLE_ID = "202342"

        @JvmStatic
        fun getIntent(context: Context, gameEntity: GameEntity, configUrl: String, entrance: String): Intent {
            return Intent(context, CloudArchiveManagerActivity::class.java).apply {
                putExtra(EntranceConsts.KEY_GAME, gameEntity)
                putExtra(EntranceConsts.KEY_ARCHIVE_CONFIG_URL, configUrl)
                putExtra(EntranceConsts.KEY_ENTRANCE, entrance)
            }
        }
    }
}