package com.gh.vspace.installexternalgames

import android.Manifest
import android.app.Dialog
import android.content.ComponentName
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.gh.common.util.DialogUtils
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.common.exposure.meta.MetaUtil
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.common.view.divider.HorizontalDividerItemDecoration
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.databinding.FragmentInstallExternalGamesBinding
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lg.vspace.VirtualAppManager
import com.lightgame.download.DownloadEntity
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers

class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {

    private val mViewModel: InstallExternalGameViewModel by lazy { viewModelProvider() }

    private lateinit var mBinding: FragmentInstallExternalGamesBinding

    private val games = mutableListOf<ExternalGameUiState>()
    private var adapter = ExternalGameAdapter(games, this)

    private var uninstallDisposable: Disposable? = null


    private var shouldScan = false

    override fun getLayoutId() = 0

    override fun getInflatedLayout() =
        FragmentInstallExternalGamesBinding.inflate(layoutInflater).apply { mBinding = this }.root

    private lateinit var dialog: Dialog


    private val requestPermissionLauncher = registerForActivityResult<String, Boolean>(
        ActivityResultContracts.RequestPermission()
    ) { result ->
        if (result == true) {
            // grant
            mViewModel.scanPaths()
        } else {
            // not grant
        }
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setNavigationTitle(getString(com.gh.gamecenter.R.string.title_install_external_game))
        initView()
        mViewModel.gamesList.observe(this) {
            if (dialog.isShowing) {
                dialog.dismiss()
            }
            games.clear()
            games.addAll(
                it.map {
                    ExternalGameUiState(it, VHelper.isInstalled(it.apkPackageName))
                }
            )
            adapter.notifyDataSetChanged()
        }


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (!Environment.isExternalStorageManager()) {
                shouldScan = true
                AlertDialog.Builder(requireContext()).setMessage("请在设置页面允许光环助手")
                    .setNegativeButton("去") { dialog, which ->
                        val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                        startActivity(intent)
                    }.show()
            } else {
                mViewModel.scanPaths()
            }
        } else {
            requestStoragePermission()
        }


    }

    private fun requestStoragePermission() {
        when {
            ContextCompat.checkSelfPermission(
                requireContext(),
                Manifest.permission.READ_EXTERNAL_STORAGE
            ) == PackageManager.PERMISSION_GRANTED -> {
                mViewModel.scanPaths()
            }

            shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE) -> {
                requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
            }

            else -> {
                requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
            }
        }
    }

    override fun onStart() {
        super.onStart()
        if (shouldScan) {
            mViewModel.scanPaths()
        }
    }

    private fun initView() {
        dialog = DialogUtils.showWaitDialog(requireContext(), "")
        mBinding.externalGamesList.let {
            it.adapter = adapter
            it.layoutManager = LinearLayoutManager(requireContext())
            val itemDecoration = HorizontalDividerItemDecoration.Builder(requireContext())
                .size(2F.dip2px())
                .color(com.gh.gamecenter.common.R.color.ui_divider.toColor(requireContext()))
                .build()
            if (it.itemDecorationCount != 0) {
                it.removeItemDecorationAt(0)
            }
            it.addItemDecoration(itemDecoration)

        }
    }

    override fun onDestroy() {
        super.onDestroy()
        if (dialog.isShowing) {
            dialog.dismiss()
        }
        if (uninstallDisposable?.isDisposed != true) {
            uninstallDisposable?.dispose()
        }
    }


    override fun onItemClick(externalGameUiState: ExternalGameUiState, clickType: OnItemClickListener.ClickType) {
        when (clickType) {
            OnItemClickListener.ClickType.CLICK_INSTALL -> {
                install(externalGameUiState)
            }

            OnItemClickListener.ClickType.CLICK_UNINSTALL -> {
                uninstall(externalGameUiState)
            }

            OnItemClickListener.ClickType.CLICK_START -> {
                start(externalGameUiState)
            }
        }
    }

    private fun install(externalGameUiState: ExternalGameUiState) {

        VHelper.disableLaunchGameAfterInstallation()
        VHelper.install(requireContext(), DownloadEntity().apply {
            externalGameUiState.externalGameEntity.apply {
                packageName = apkPackageName
                path = apkPath
            }
        }, true)

        VHelper.newCwValidateVspaceBeforeAction(
            requireContext(), null,
        ) {
            dialog.show()
        }

    }

    private fun uninstall(externalGameUiState: ExternalGameUiState) {
        dialog.show()
        uninstallDisposable = Single.create<Void> {
            VHelper.uninstall(externalGameUiState.externalGameEntity.apkPackageName)
        }.subscribeOn(Schedulers.from(AppExecutor.lightWeightIoExecutor)).observeOn(AndroidSchedulers.mainThread())
            .subscribe { t1, t2 ->
                if (dialog.isShowing) {
                    dialog.dismiss()
                }
            }
    }


    private fun start(externalGameUiState: ExternalGameUiState) {
        val intent = VirtualAppManager.get().getStartGameIntent(
            externalGameUiState.externalGameEntity.apkPackageName,
            "",
            externalGameUiState.externalGameEntity.appName,
            "",
            MetaUtil.getBase64EncodedAndroidId(),
            HaloApp.getInstance().gid,
            com.gh.gamecenter.BuildConfig.VERSION_NAME,
            HaloApp.getInstance().channel,
            "",
            "",
            com.gh.gamecenter.BuildConfig.VA_VERSION_NAME,
            HaloApp.getInstance().oaid
        )
        intent.setComponent(
            ComponentName(
                com.gh.gamecenter.BuildConfig.APPLICATION_ID,
                VirtualAppManager.AIDL_SERVER_REMOTE_GUIDE_ACTIVITY
            )
        )
        requireActivity().startActivity(intent)
    }


}