package com.gh.gamecenter

import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Build
import android.os.Bundle
import android.preference.PreferenceManager
import android.text.method.ScrollingMovementMethod
import android.view.KeyEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.app.ActivityCompat
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.alibaba.android.arouter.facade.annotation.Route
import com.g00fy2.versioncompare.Version
import com.gh.common.constant.Config
import com.gh.common.dialog.NewPrivacyPolicyDialogFragment
import com.gh.common.util.*
import com.gh.common.util.DialogUtils
import com.gh.common.util.GameSubstituteRepositoryHelper.updateGameSubstituteRepository
import com.gh.common.util.UsageStatsHelper.checkAndPostUsageStats
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.callback.SimpleCallback
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.tracker.TrackerLogger
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.PrivacyPolicyEntity
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.FileUtils
import pub.devrel.easypermissions.AfterPermissionGranted
import pub.devrel.easypermissions.EasyPermissions
import java.io.BufferedReader
import java.io.File
import java.io.IOException
import java.io.InputStreamReader
import java.text.SimpleDateFormat
import java.util.*

/**
 * 引导页面
 */
@Route(path = RouteConsts.activity.splashActivity)
class SplashScreenActivity : BaseActivity() {

    private var mSharedPreferences: SharedPreferences? = null
    private var mIsNewForThisVersion = false
    private var mStartMainActivityDirectly = false // 是否不需要用户点击立即体验就直接跳转首页
    private var mViewModel: SplashScreenViewModel? = null
    private var mShouldPrefetchData = true

    private val mPermissions = arrayOf(
        Manifest.permission.WRITE_EXTERNAL_STORAGE,
        Manifest.permission.READ_EXTERNAL_STORAGE,
        PermissionHelper.PERMISSION_GET_INSTALLED_LIST
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        mViewModel = viewModelProvider()
        mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
        mIsNewForThisVersion =
            mSharedPreferences!!.getBoolean("isNewFirstLaunchV" + PackageUtils.getGhVersionName(), true)
        HaloApp.getInstance().isNewForThisVersion = mIsNewForThisVersion

        // 用户不是新版本，但应用最后更新时间不是上次的时间代表用户重新安装了当前版本
        if (!mIsNewForThisVersion) {
            val ghLastUpdateTime = SPUtils.getLong(Constants.SP_GH_LAST_UPDATE_TIME, 0)
            if (ghLastUpdateTime != 0L && ghLastUpdateTime != PackageUtils.getHaloLastUpdateTime()) {
                HaloApp.getInstance().setIsReinstallTheSameVersion(true)
            }
        }
        super.onCreate(savedInstanceState)
        DisplayUtils.transparentStatusBar(this)
        TrackerLogger.logAppLaunch(this)

        // 处理助手已经在后台运行导致的再次启动助手
        if (intent.flags and Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT != 0) {
            finish()
            return
        }

        // 判断是不是这个版本的新用户
        if (mIsNewForThisVersion) {
            mContentView.setPadding(0, 0, 0, 0)
            val guideLayout = findViewById<ViewPager>(R.id.splash_intro_vp_guide)
            guideLayout.adapter = GuidePagerAdapter()

            // 判断是不是光环的新用户
            if (SPUtils.getBoolean(Constants.SP_BRAND_NEW_USER, true)) {
                // 引导页需用户点击 “立即体验” 按钮才进入首页，所以这里不能置为true
                // https://git.ghzs.com/pm/halo-app-issues/-/issues/1422（第3点）
//                mStartMainActivityDirectly = true;
                SPUtils.setLong(Constants.SP_INITIAL_USAGE_TIME, System.currentTimeMillis())
                HaloApp.getInstance().isBrandNewInstall = true
                if (!PackageFlavorHelper.IS_TEST_FLAVOR) {
                    showPrivacyDialog(guideLayout)
                } else {
                    // Test dex2oat
                    executeDex2OatInAdvance()
                    DialogHelper.showDialog(
                        this,
                        "选择接口环境",
                        "这个弹窗只会在右上角有环境标签的测试包出现\n进入应用以后还可以到关于我们页面长按应用图标重新选择",
                        "正式环境",
                        "测试环境",
                        object : EmptyCallback {
                            override fun onCallback() {
                                SPUtils.setBoolean(Constants.SP_IS_DEV_ENV, false)
                                showPrivacyDialog(guideLayout)
                            }
                        },
                        object : EmptyCallback {
                            override fun onCallback() {
                                SPUtils.setBoolean(Constants.SP_IS_DEV_ENV, true)
                                showPrivacyDialog(guideLayout)
                            }

                        },
                        false,
                        "",
                        ""
                    )
                }
            } else {
                cancelPreviousUpdateTask()
                guideLayout.visibility = View.VISIBLE
                //requestPermission()
            }
        } else {
            if (com.gh.gamecenter.common.BuildConfig.BUILD_TIME != 0L) {
                showGitLogDialogIfNeeded()
            } else {
                launchMainActivity()
            }
        }
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
            SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "")
            SPUtils.setString(Constants.SP_XAPK_URL, "")
        }
    }

    private fun showPrivacyDialog(guideLayout: ViewPager) {
        NewPrivacyPolicyDialogFragment.show(this, null) { isSuccess: Boolean ->
            if (isSuccess) {
//                guideLayout.visibility = View.VISIBLE
//                SPUtils.setBoolean(Constants.SP_BRAND_NEW_USER, false)
//
//                // 恢复畅玩数据
//                VHelper.recoverVDataIfPossible()
//
//                requestPermission()
//
//                // 检查是否有旧版本光环，有就删掉
//                AppExecutor.ioExecutor.execute { deleteOutdatedUpdatePackage() }
//                if (mStartMainActivityDirectly) {
//                    launchMainActivity()
//                }

                mShouldPrefetchData = false
                prefetchData()

                val callback = object : SimpleCallback<Boolean> {
                    override fun onCallback(arg: Boolean) {
                        // Dialog dismiss 后的回调
                        guideLayout.visibility = View.VISIBLE
                        SPUtils.setBoolean(Constants.SP_BRAND_NEW_USER, false)
                        if (arg) {
                            requestPermission()
                        } else {
                            mStartMainActivityDirectly = false
                        }
                    }
                }

                mViewModel?.showPrivacyPolicy({
                    DialogUtils.showPrivacyPolicyDialog(this@SplashScreenActivity, it, callback)
                }, {
                    DialogUtils.showPrivacyPolicyDialog(this@SplashScreenActivity, PrivacyPolicyEntity.createDefaultData(), callback)
                })
            } else {
                DialogUtils.showPrivacyPolicyDisallowDialog(
                    this,
                    PrivacyPolicyEntity.createDefaultData(),
                    object : EmptyCallback {
                        override fun onCallback() {
                            showPrivacyDialog(guideLayout)
                        }
                    })
            }
        }
    }

    // 删除更新后的光环助手包
    private fun cancelPreviousUpdateTask() {
        val all = DownloadManager.getInstance().allDownloadEntity
        for (downloadEntity in all) {
            if (downloadEntity.packageName == packageName) {
                DownloadManager.getInstance().cancel(downloadEntity.url, true, true, false)
                break
            }
        }
    }

    /**
     * 让系统执行 dex2oat
     */
    private fun executeDex2OatInAdvance() {
        try {
            Runtime.getRuntime().exec("cmd package compile -m speed -f " + BuildConfig.APPLICATION_ID)
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }

    private fun requestPermission() {
        if (!EasyPermissions.hasPermissions(this, *mPermissions)) {
            checkAndRequestPermission()
        }
    }

    override fun getLayoutId(): Int {
        return if (mIsNewForThisVersion) {
            R.layout.activity_splash_intro
        } else 0
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.repeatCount == 0) {
            if (mIsNewForThisVersion && EasyPermissions.hasPermissions(this, *mPermissions)) {
                if (com.gh.gamecenter.common.BuildConfig.BUILD_TIME != 0L) {
                    showGitLogDialogIfNeeded()
                } else {
                    launchMainActivity()
                }
            } else {
                return true
            }
        }
        return super.onKeyDown(keyCode, event)
    }

    override fun useEventBus() = false

    // 跳转到主界面
    private fun launchMainActivity() {
        SPUtils.setLong(Constants.SP_GH_LAST_UPDATE_TIME, PackageUtils.getHaloLastUpdateTime())
        HaloApp.getInstance().postInit(true)
        TrackerLogger.logAppLaunchSuccessful()
        if (mShouldPrefetchData) {
            prefetchData()
        }
        val bundle = intent.extras
        val intent = Intent(this@SplashScreenActivity, MainActivity::class.java)
        if (bundle != null) {
            intent.putExtras(bundle)
        }
        intent.putExtra(MainActivity.SHOW_AD, !mIsNewForThisVersion)
        overridePendingTransition(0, 0)
        startActivity(intent)
        uploadTeaData()
        finish()
    }

    private fun getGitLogString(): String {
        if (com.gh.gamecenter.common.BuildConfig.BUILD_TIME != 0L) {
            val stringBuilder = StringBuilder()
            var bufferedReader: BufferedReader? = null
            var inputStreamReader: InputStreamReader? = null
            try {
                inputStreamReader = InputStreamReader(assets.open("gitlog.txt"))
                bufferedReader = BufferedReader(inputStreamReader)
                var line: String?
                stringBuilder.append("本光环安装包最近20次代码变更如下：")
                stringBuilder.append(System.getProperty("line.separator"))
                while (bufferedReader.readLine().also { line = it } != null) {
                    line?.let {
                        val urlRegex = Regex("http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?")
                        if (urlRegex.containsMatchIn(it)) {
                            line = urlRegex.replace(it, "")
                        }
                    }
                    stringBuilder.append(line)
                    stringBuilder.append(System.getProperty("line.separator"))
                }
            } catch (e: IOException) {
                e.printStackTrace()
            } finally {
                inputStreamReader?.close()
                bufferedReader?.close()
            }
            return stringBuilder.toString()
        } else {
            return ""
        }
    }

    private fun showGitLogDialogIfNeeded() {
        if (com.gh.gamecenter.common.BuildConfig.BUILD_TIME != 0L) {
            val gitLog = getGitLogString()
            if (gitLog.isNotEmpty()) {
                val md5 = MD5Utils.getContentMD5(gitLog)
                if (SPUtils.getString(Constants.GIT_LOG_MD5, "") != md5) {
                    DialogHelper.showDialog(
                        this,
                        "${PackageUtils.getGhVersionName()} ${com.gh.gamecenter.common.BuildConfig.BUILD_TIME}",
                        gitLog,
                        "确定",
                        "",
                        {
                            SPUtils.setString(Constants.GIT_LOG_MD5, md5)
                            launchMainActivity()
                        },
                        extraConfig = DialogHelper.Config(
                            centerTitle = true,
                            centerContent = false
                        ),
                        uiModificationCallback = { binding ->
                            binding.contentTv.run {
                                maxHeight = 500F.dip2px()
                                textSize = 10F
                                isVerticalScrollBarEnabled = true
                                movementMethod = ScrollingMovementMethod.getInstance()
                            }
                        })
                } else {
                    launchMainActivity()
                }
            } else {
                launchMainActivity()
            }
        }
    }

    private fun uploadTeaData() {
        if ("tea" == BuildConfig.FLAVOR) {
            // 在可能获取了相关权限后才初始化SDK/发送激活数据
//        TeaHelper.init(getApplication(), HaloApp.getInstance().getChannel());
            try {
                val clazz = Class.forName("com.gh.gamecenter.TeaHelper")
                val method = clazz.getMethod("init", Context::class.java, String::class.java)
                method.invoke(null, application, HaloApp.getInstance().channel)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    private fun prefetchData() {
        runOnIoThread {
            Config.getGhzsSettings()
            mViewModel?.deviceDialogSetting()
            mViewModel?.filterDetailTags()
            mViewModel?.authDialog()
            mViewModel?.postMark(mIsNewForThisVersion)
            mViewModel?.regulationTestStatus()
            checkAndPostUsageStats()
            updateGameSubstituteRepository()

            // 获取自动刷新的cd，获取版本对应表
            val time = mSharedPreferences!!.getString("refresh_time", null)
            val format = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
            val today = format.format(Date())
            if (today != time) {
                // 获取版本代码、名称
                PlatformUtils.getInstance(applicationContext).getPlatform()
                TagUtils.getInstance(applicationContext).getTag()
            }

            // 更新本地时间
            DeviceTokenUtils.syncServerTime(this)
        }
    }

    @AfterPermissionGranted(REQUEST_PERMISSION_TAG)
    private fun checkAndRequestPermission() {
        if (EasyPermissions.hasPermissions(this, *mPermissions)) {
            // 恢复畅玩数据
            VHelper.recoverVDataIfPossible()

            // 检查是否有旧版本光环，有就删掉
            runOnIoThread { deleteOutdatedUpdatePackage() }
            if (mStartMainActivityDirectly) {
                if (com.gh.gamecenter.common.BuildConfig.BUILD_TIME != 0L) {
                    showGitLogDialogIfNeeded()
                } else {
                    launchMainActivity()
                }
            }
        } else {
            ActivityCompat.requestPermissions(this, mPermissions, REQUEST_PERMISSION_TAG)
        }
    }

    override fun onPermissionsDenied(requestCode: Int, perms: List<String>) {
        if (mStartMainActivityDirectly) {
            if (com.gh.gamecenter.common.BuildConfig.BUILD_TIME != 0L) {
                showGitLogDialogIfNeeded()
            } else {
                launchMainActivity()
            }
        }
    }

    // 检查下载文件夹下是否有旧版本的光环助手的包，有则删除
    private fun deleteOutdatedUpdatePackage() {
        try {
            val folder = File(FileUtils.getDownloadDir(this) + File.separator)
            if (folder.isDirectory) {
                for (file in folder.listFiles()) {
                    if (!file.isDirectory && file.name.startsWith("光环助手V")) {
                        val name = file.name
                        val index = name.indexOf("_")
                        if (index != -1) {
                            val versionString = name.substring(name.indexOf("V") + 1, index)
                            val currentVersion = Version(PackageUtils.getGhVersionName())
                            if (currentVersion.isHigherThan(versionString) || currentVersion.isEqual(versionString)) {
                                file.delete()
                            }
                        }
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private inner class GuidePagerAdapter : PagerAdapter() {
        private val mPics = intArrayOf(R.drawable.splash_01)
        override fun getCount(): Int {
            return mPics.size
        }

        override fun instantiateItem(container: ViewGroup, position: Int): Any {
            val view = View.inflate(container.context, R.layout.splash_guide_item, null)
            val ivImage = view.findViewById<ImageView>(R.id.splsh_guide_iv_image)
            ivImage.setImageResource(mPics[position])
            if (position == mPics.size - 1) {
                val tvSkip = view.findViewById<TextView>(R.id.splsh_guide_tv_skip)
                tvSkip.setOnClickListener {
                    if (com.gh.gamecenter.common.BuildConfig.BUILD_TIME != 0L) {
                        showGitLogDialogIfNeeded()
                    } else {
                        launchMainActivity()
                    }
                }
            }
            container.addView(view)
            return view
        }

        override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
            container.removeView(`object` as View)
        }

        override fun isViewFromObject(view: View, `object`: Any): Boolean {
            return view === `object`
        }
    }

    companion object {
        private const val REQUEST_PERMISSION_TAG = 30001

        @JvmStatic
        fun getSplashScreenIntent(context: Context?, bundle: Bundle?): Intent {
            val intent = Intent(context, SplashScreenActivity::class.java)
            intent.action = Intent.ACTION_MAIN
            intent.addCategory(Intent.CATEGORY_LAUNCHER)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            intent.putExtras(bundle ?: Bundle())
            return intent
        }
    }
}