package com.gh.vspace

import android.content.Context
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.databind.BindingAdapters
import com.gh.common.exposure.IExposable
import com.gh.common.util.NewFlatLogUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.ItemViewType
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.SpeedUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.ItemVgameDownloadManagerBinding
import com.gh.gamecenter.databinding.PopupHistoryOptionBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.gamecenter.history.ManageOption
import com.gh.gamecenter.manager.PackagesManager
import com.gh.vspace.menu.VDownLoadManagerItemMenuDialog
import com.gh.vspace.shortcut.OnCreateShortcutResult
import com.gh.vspace.shortcut.ShortcutManager
import com.gh.vspace.shortcut.ShortcutPermissionDialog
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.utils.Utils
import com.muugi.shortcut.core.Executor
import org.json.JSONArray

class VDownloadManagerAdapter(
    context: Context,
    private val mFragmentManager: FragmentManager,
    private val mViewModel: VDownloadManagerViewModel,
) : ListAdapter<GameEntity>(context), IExposable {

    private val mBasicExposureSource by lazy {
        if (mViewModel.isFromHomeRecent) listOf(ExposureSource("新首页"), ExposureSource("最近在玩"))
        else listOf()
    }

    private var mPopWindow: PopupWindow? = null
    private var mCurrentOption = ManageOption.OPTION_MANAGER
    private var mPopupBinding: PopupHistoryOptionBinding? = null
    private var mItemMenuDialog: VDownLoadManagerItemMenuDialog? = null

    var selectItems = arrayListOf<String>()

    private val mPositionAndPackageMap = HashMap<String, Int>()

    override fun setListData(updateData: MutableList<GameEntity>?) {
        mPositionAndPackageMap.clear()
        // 记录游戏位置
        if (updateData != null) {
            for (i in 0 until updateData.size) {
                val gameEntity = updateData[i]
                var packages = gameEntity.id
                for (apkEntity in gameEntity.getApk()) {
                    packages += apkEntity.packageName
                }
                mPositionAndPackageMap[packages + i] = i
            }
        }

        if (updateData == null) {
            mEntityList = ArrayList()
            notifyDataSetChanged()
            return
        }

        calculateDiff(updateData)
    }

    override fun areItemsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean {
        return oldItem != null && oldItem.id == newItem?.id
    }

    override fun areContentsTheSame(oldItem: GameEntity?, newItem: GameEntity?): Boolean {
        return oldItem?.id == newItem?.id
    }

    override fun getItemViewType(position: Int) = ItemViewType.GAME_NORMAL

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return VGameItemViewHolder(parent.toBinding())
    }

    override fun getItemCount(): Int =
        if (mEntityList == null || mEntityList.isEmpty()) 0 else mEntityList.size

    fun changeOption(option: ManageOption) {
        mCurrentOption = option
        when (mCurrentOption) {
            ManageOption.OPTION_MANAGER -> {
                selectItems.clear()
                mPopWindow?.dismiss()
                mPopWindow = null
            }
            else -> {
                if (mPopWindow == null || mPopWindow?.isShowing == false) {
                    showOptionWindow()
                }
            }
        }
        notifyItemRangeChanged(0, mEntityList.size)
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is VGameItemViewHolder -> {
                val gameEntity = mEntityList[position]

                if (mViewModel.isTypeDownloaded()) {
                    runOnIoThread(true) {
                        gameEntity.exposureEvent = ExposureEvent.createEventWithSourceConcat(
                            gameEntity = gameEntity,
                            basicSource = mBasicExposureSource,
                            source = listOf(ExposureSource("畅玩游戏管理"))
                        )
                    }
                }

                BindingAdapters.setGameName(holder.binding.nameTv, gameEntity, false)
                holder.binding.iconIv.displayGameIcon(gameEntity)

                holder.binding.descTv.goneIf(mViewModel.isTypeDownloaded() && gameEntity.des?.isEmpty() == true)
                if (mViewModel.isTypeDownloaded()) {
                    holder.binding.descTv.text = gameEntity.des
                } else {
                    holder.binding.descTv.layoutParams =
                        (holder.binding.descTv.layoutParams as MarginLayoutParams).apply {
                            setMargins(
                                0,
                                8F.dip2px(),
                                0,
                                0
                            )
                        }
                }

                holder.binding.selectIv.setImageDrawable(DrawableView.getCheckSelectorDrawable(mContext))
                holder.binding.selectIv.goneIf(mCurrentOption == ManageOption.OPTION_MANAGER)
                holder.binding.selectIv.isChecked = selectItems.contains(gameEntity.id)

                holder.itemView.setOnClickListener {
                    if (mCurrentOption == ManageOption.OPTION_MANAGER) {
                        GameDetailActivity.startGameDetailActivity(
                            mContext, gameEntity.id, "(畅玩游戏管理)"
                        )
                    } else {
                        if (selectItems.contains(gameEntity.id)) {
                            selectItems.remove(gameEntity.id)
                        } else {
                            selectItems.add(gameEntity.id)
                        }
                        checkSelectItems()
                        notifyItemChanged(position)
                    }
                }

                val entityFromDownloadManager = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
                val entityFromVGame = VHelper.getVDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName())

                val downloadEntity =
                    if (entityFromDownloadManager != null && entityFromDownloadManager.status != DownloadStatus.cancel) {
                        entityFromDownloadManager
                    } else {
                        entityFromVGame
                    }

                updateDownloadBtnAndDes(
                    mContext,
                    downloadEntity,
                    holder.binding.downloadBtn,
                    holder.binding.descTv,
                    gameEntity
                )

                holder.itemView.setOnLongClickListener {
                    val autoPause = downloadEntity?.status == DownloadStatus.downloading
                    if (autoPause) {
                        holder.binding.downloadBtn.performClick()
                    }
                    //还在下载中的游戏直接弹出删除对话框
                    if (!mViewModel.isTypeDownloaded()) {
                        showDelGameDialog(holder, autoPause, gameEntity)
                        return@setOnLongClickListener false
                    }
                    //下载完成的在玩游戏才有菜单
                    if (mItemMenuDialog == null) {
                        mItemMenuDialog = VDownLoadManagerItemMenuDialog()
                    } else {
                        mItemMenuDialog?.dismiss()
                    }
                    mItemMenuDialog?.onAddIconToLauncherClickListener = {
                        //添加到桌面
                        addShortcutToLauncher(holder, gameEntity)
                    }
                    mItemMenuDialog?.onClearGameDataClickListener = {
                        //清除游戏数据
                        showCLearGameDataDialog(holder, gameEntity)
                    }
                    mItemMenuDialog?.onDeleteGameClickListener = {
                        showDelGameDialog(holder, autoPause, gameEntity)
                    }
                    NewFlatLogUtils.logHaloFunGameMoreDialogShow(
                        gameEntity?.id ?: "",
                        gameEntity?.name ?: ""
                    )
                    mItemMenuDialog?.show(mFragmentManager, null)
                    return@setOnLongClickListener false
                }
            }
            is FooterViewHolder -> {
                holder.initItemPadding()
                holder.initFooterViewHolder(mViewModel, mIsLoading, mIsNetworkError, mIsOver)
            }
        }
    }

    /**
     * 显示添加图标到桌面的对话框
     */
    private fun addShortcutToLauncher(holder: VGameItemViewHolder, gameEntity: GameEntity) {
        val context = holder.binding.root.context
        ShortcutManager.getInstance()
            .tryCreateShortCut(
                context, gameEntity,
                object : OnCreateShortcutResult {
                    override fun showPermissionDialog(executor: Executor?) {
                        NewFlatLogUtils.logHaloFunShortcutPermissionDialogShow(
                            gameEntity.id,
                            gameEntity.name ?: ""
                        )
                        ShortcutPermissionDialog(context, gameEntity, executor).show()
                    }

                    override fun exist() {
                        ToastUtils.showToast(context.getString(R.string.shortcut_exist))
                    }

                    override fun success() {
                        ToastUtils.showToast(context.getString(R.string.shortcut_create_success))
                    }

                    override fun failed() {
                        ToastUtils.showToast(context.getString(R.string.shortcut_create_failed))
                    }

                })
    }

    /**
     * 显示清除游戏数据对话框
     */
    private fun showCLearGameDataDialog(holder: VGameItemViewHolder, gameEntity: GameEntity) {
        NewFlatLogUtils.logHaloFunCleanDataDialogShow(
            gameEntity.id,
            gameEntity.name ?: ""
        )
        DialogHelper.showDialog(
            holder.binding.root.context,
            "提示",
            "清除后游戏的所有记录都将被清空，无法恢复！您确定要清除吗？",
            "确定",
            "取消",
            confirmClickCallback = { //清除游戏数据
                mViewModel.cleanGameData(gameEntity.getUniquePackageName())
                NewFlatLogUtils.logHaloFunCleanDataDialogButtonClick(
                    gameEntity.id,
                    gameEntity.name ?: "",
                    "确定"
                )
            },
            cancelClickCallback = {
                NewFlatLogUtils.logHaloFunCleanDataDialogButtonClick(
                    gameEntity.id,
                    gameEntity.name ?: "",
                    "取消"
                )
            },
            extraConfig = DialogHelper.Config(centerTitle = true)
        )
    }

    /**
     * 显示删除游戏的对话框
     */
    private fun showDelGameDialog(
        holder: VGameItemViewHolder,
        autoPause: Boolean,
        gameEntity: GameEntity
    ) {
        DialogHelper.showDialog(
            holder.binding.root.context,
            "删除游戏",
            "单机类游戏被删除将可能导致本地存档、充值数据丢失，请确认后操作（网游类游戏删除不会影响游戏存档和充值数据）",
            "再等等",
            "删除",
            {
                if (autoPause) {
                    holder.binding.downloadBtn.performClick()
                }
            },
            {
                //删除对应的桌面快捷方式
                ShortcutManager.getInstance().removeShortcut(holder.binding.root.context, gameEntity)
                runOnIoThread {
                    val apk = gameEntity.getApk().firstOrNull()
                    mViewModel.removeItem(apk?.url, apk?.packageName)

                    AppExecutor.uiExecutor.executeWithDelay({
                        mViewModel.load(LoadType.REFRESH)
                    }, 200)
                }
            },
            uiModificationCallback = {
                it.cancelTv.setTextColor(com.gh.gamecenter.common.R.color.secondary_red.toColor(it.root.context))
                it.confirmTv.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(it.root.context))
            },
            extraConfig = DialogHelper.Config(centerTitle = true)
        )?.setOnCancelListener {
            if (autoPause) {
                holder.binding.downloadBtn.performClick()
            }
        }
    }

    private fun showOptionWindow() {
        mPopupBinding = PopupHistoryOptionBinding.inflate(LayoutInflater.from(mContext))
        mPopupBinding?.root?.isFocusable = true
        mPopupBinding?.root?.isFocusableInTouchMode = true

        mPopWindow =
            PopupWindow(mPopupBinding?.root, LinearLayout.LayoutParams.MATCH_PARENT, 56F.dip2px())
        mPopWindow?.showAtLocation(
            (mContext as AppCompatActivity).window.decorView, Gravity.BOTTOM, 0, 0
        )

        mPopupBinding?.itemDelete?.setOnClickListener {
            NewFlatLogUtils.logHaloFunEvent("halo_fun_manage_game_delete_dialog_show")
            mViewModel.pauseItems(ArrayList(selectItems))
            DialogHelper.showDialog(
                mContext,
                "删除游戏",
                "单机类游戏被删除将可能导致本地存档、充值数据丢失，请确认后操作（网游类游戏删除不会影响游戏存档和充值数据）",
                "再等等",
                "删除",
                {
                    NewFlatLogUtils.logHaloFunManageGameDeleteDialogClick(
                        "再看看", JSONArray(selectItems)
                    )
                },
                {
                    NewFlatLogUtils.logHaloFunManageGameDeleteDialogClick(
                        "删除", JSONArray(selectItems)
                    )

                    val selectItemCopy = ArrayList(selectItems)

                    selectItems.clear()
                    checkSelectItems()
                    changeOption(ManageOption.OPTION_MANAGER)

                    runOnIoThread {
                        mViewModel.removeItems(selectItemCopy)
                        AppExecutor.uiExecutor.executeWithDelay({
                            mViewModel.load(LoadType.REFRESH)
                        }, 200)
                    }
                },
                uiModificationCallback = {
                    it.cancelTv.setTextColor(com.gh.gamecenter.common.R.color.secondary_red.toColor(it.root.context))
                    it.confirmTv.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(it.root.context))
                },
                extraConfig = DialogHelper.Config(centerTitle = true)
            )
        }
        mPopupBinding?.checkAllCb?.setCompoundDrawablesWithIntrinsicBounds(
            DrawableView.getCheckSelectorDrawable(
                mContext
            ), null, null, null
        )
        mPopupBinding?.checkAllCb?.setOnClickListener {
            if (mPopupBinding?.checkAllCb?.isChecked == true) {
                selectItems.clear()
                selectItems.addAll(mEntityList.map { it.id }.toList())
            } else {
                selectItems.clear()
            }
            checkSelectItems()
            notifyItemRangeChanged(0, mEntityList.size)
        }
        checkSelectItems()
    }

    fun updatePopupWindow() {
        mPopupBinding?.run {
            root.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(mContext))
            checkAllCb.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(mContext))
            selectNumTv.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(mContext))
            checkAllCb.setDrawableStart(DrawableView.getCheckSelectorDrawable(mContext))
            checkSelectItems()
        }
    }

    private fun checkSelectItems() {
        mPopupBinding?.run {
            selectNumTv.text = if (selectItems.isEmpty()) "" else "(${selectItems.size})"
            itemDelete.background =
                if (selectItems.isEmpty()) com.gh.gamecenter.feature.R.drawable.button_round_gray_light.toDrawable(mContext) else com.gh.gamecenter.common.R.drawable.download_button_normal_style.toDrawable(
                    mContext
                )
            itemDelete.setTextColor(
                if (selectItems.isEmpty()) com.gh.gamecenter.common.R.color.text_secondary.toColor(mContext) else com.gh.gamecenter.common.R.color.white.toColor(
                    mContext
                )
            )
            itemDelete.isEnabled = selectItems.isNotEmpty()
            checkAllCb.isChecked = selectItems.size == mEntityList.size
        }
    }

    fun notifyItemByDownload(download: DownloadEntity) {
        for (key in mPositionAndPackageMap.keys) {
            if (key.contains(download.packageName) && key.contains(download.gameId)) {
                val position = mPositionAndPackageMap[key]
                if (position != null && mEntityList != null && position < mEntityList.size) {
                    mEntityList[position].getEntryMap()[download.platform] = download
                    notifyItemChanged(position)
                }
            }
        }
    }

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

        downloadBtn.goneIf(mCurrentOption != ManageOption.OPTION_MANAGER)

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

            downloadBtn.apply {
                when (status) {
                    DownloadStatus.downloading -> {
                        btnText = "${downloadEntity.percent}%"
                        downloadDes.visibility = View.VISIBLE
                        val speedText = SpeedUtils.getSpeed(downloadEntity.speed)
                        val remainTimeText = SpeedUtils.getRemainTime(
                            downloadEntity.size,
                            downloadEntity.progress,
                            downloadEntity.speed * 1024
                        )
                        downloadDes.text = "$speedText(剩$remainTimeText)"
                        downloadDes.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(mContext))
                        backgroundType = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
                        progress = (downloadEntity.percent * 10).toInt()
                        setOnClickListener {
                            DownloadManager.getInstance().pause(downloadEntity.url)
                        }
                    }
                    DownloadStatus.waiting -> {
                        btnText = context.getString(com.gh.gamecenter.feature.R.string.waiting)
                        backgroundType = DownloadButton.ButtonStyle.WAITING
                        downloadDes.visibility = View.VISIBLE
                        downloadDes.text = context.getString(com.gh.gamecenter.feature.R.string.waiting)
                        downloadDes.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(mContext))
                        setOnClickListener { Utils.toast(mContext, "最多只能同时下载三个任务，请稍等"); }
                    }
                    DownloadStatus.pause,
                    DownloadStatus.timeout,
                    DownloadStatus.neterror,
                    DownloadStatus.subscribe,
                    DownloadStatus.diskioerror,
                    DownloadStatus.diskisfull,
                    DownloadStatus.overflow -> {
                        btnText = context.getString(com.gh.gamecenter.feature.R.string.resume)
                        downloadDes.visibility = View.VISIBLE
                        downloadDes.text = if (status == DownloadStatus.subscribe) "等待WIFI" else "已暂停"
                        downloadDes.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(mContext))
                        setOnClickListener {
                            DownloadManager.getInstance().resume(downloadEntity, false)
                        }
                    }
                    DownloadStatus.done -> {
                        if (PackagesManager.isCanUpdate(
                                gameId = gameEntity.id,
                                packageName = gameEntity.getApk().firstOrNull()?.packageName,
                                asVGame = true
                            )
                        ) {
                            btnText = context.getString(com.gh.gamecenter.feature.R.string.update)
                            setOnClickListener {
                                PackagesManager.getUpdateList()
                                    .firstOrNull { it.id == downloadEntity.gameId }?.let {
                                        VHelper.updateOrReDownload(downloadEntity, it)
                                    }
                            }
                        } else {
                            btnText = context.getString(com.gh.gamecenter.feature.R.string.launch)
                            setOnClickListener {
                                CurrentActivityHolder.getCurrentActivity()?.let {
                                    VHelper.installOrLaunch(it, downloadEntity, "畅玩管理")
                                }
                            }
                        }
                    }
                    else -> {
                        // do nothing
                    }
                }

                text = btnText.toString()
                buttonStyle = backgroundType
            }
        } else {
            downloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
            downloadBtn.text = "下载"
            downloadBtn.setOnClickListener {
                ToastUtils.toast("不应该出现状态为'下载'的按钮")
            }
        }
    }

    override fun getEventByPosition(pos: Int) = mEntityList[pos].exposureEvent

    override fun getEventListByPosition(pos: Int): List<ExposureEvent>? = null

    class VGameItemViewHolder(var binding: ItemVgameDownloadManagerBinding) :
        RecyclerView.ViewHolder(binding.root)

}