package com.gh.ndownload.suspendwindow

import android.app.Activity
import android.app.Application
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Bundle
import androidx.core.view.ViewCompat
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.asVGame
import com.gh.gamecenter.common.utils.categoryChinese
import com.gh.gamecenter.common.utils.getMetaExtra
import com.gh.ndownload.NDataChanger
import com.gh.ndownload.suspendwindow.data.NDownloadState
import com.gh.ndownload.suspendwindow.utils.NDownloadSuspendWindowHelper
import com.gh.ndownload.suspendwindow.window.NDownloadDrawOverlayPermissionWindow
import com.gh.ndownload.suspendwindow.window.NDownloadSuspendIconWindow
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import java.lang.ref.WeakReference

/**
 * 下载引导开启悬浮窗-控制器
 */
class NDownloadDrawOverlayPermissionWindowController(val application: Application) : ActivityLifecycleCallbacks {

    private var isStarted = false

    private var currentDownloadEntity: DownloadEntity? = null

    private var onGrantDrawOverlayPermissionListener: OnGrantDrawOverlayPermissionListener? = null

    private var contentWindow: NDownloadDrawOverlayPermissionWindow? = null

    private var iconWindow: NDownloadSuspendIconWindow? = null

    private var currentActivityRef: WeakReference<Activity>? = null

    private val downloadObserver by lazy {
        object : DataWatcher() {
            override fun onDataChanged(downloadEntity: DownloadEntity) {
                onDownloadChanged(downloadEntity)
            }
        }
    }

    fun show(activity: Activity) {
        val decorView = activity.window.decorView
        val isAttachedToWindow = ViewCompat.isAttachedToWindow(decorView)
        if (isStarted || !isAttachedToWindow) return
        isStarted = true
        currentActivityRef = WeakReference(activity)
        onAttachToUi(activity)
        initCurrentDownloadEntity()
        NDataChanger.addObserver(downloadObserver)
        application.registerActivityLifecycleCallbacks(this)
        trackDownloadSuspendedWindowGuideShow()
    }

    fun dismiss() {
        if (!isStarted) return

        currentDownloadEntity = null
        currentActivityRef = null
        onDetachFromUi()
        NDataChanger.deleteObserver(downloadObserver)
        application.unregisterActivityLifecycleCallbacks(this)
        isStarted = false
    }

    private fun onAttachToUi(activity: Activity) {
        iconWindow = NDownloadSuspendIconWindow(
            activity,
            suspend = false,
            draggable = false
        ).also {
            it.attach()
        }
        contentWindow = NDownloadDrawOverlayPermissionWindow(
            activity,
            false
        ).also {
            it.attach()
            it.setOnCloseClickListener {
                dismiss()
            }
            it.setOnButtonClickListener {
                NDownloadSuspendWindowHelper
                    .requestDrawOverlayPermission(
                        activity,
                        0,
                        "悬浮窗引导图"
                    )
                trackDownloadSuspendedWindowGuideClick()
            }
        }
    }

    private fun onDetachFromUi() {
        contentWindow?.detach()
        iconWindow?.detach()
        contentWindow = null
        iconWindow = null
    }


    fun setOnGrantDrawOverlayPermissionListener(listener: OnGrantDrawOverlayPermissionListener?) {
        this.onGrantDrawOverlayPermissionListener = listener
    }

    fun setCurrentDownloadEntity(downloadEntity: DownloadEntity) {
        if (!isStarted) this.currentDownloadEntity = downloadEntity
    }

    private fun initCurrentDownloadEntity(): Boolean =
        this.currentDownloadEntity?.let { downloadEntity ->
            NDownloadSuspendWindowHelper.getIconDownloadState(downloadEntity)?.let {
                updateCurrentDownloadEntity(downloadEntity)
                updateDownloadIconAndState(downloadEntity.icon ?: "", it)
                true
            } ?: false
        } ?: false

    private fun trackDownloadSuspendedWindowGuideShow() {
        this.currentDownloadEntity?.let { downloadEntity ->
            SensorsBridge.trackDownloadSuspendedWindowGuideShow(
                gameId = downloadEntity.gameId,
                gameName = downloadEntity.name,
                gameSchemaType = if (downloadEntity.getMetaExtra(Constants.KEY_BIT) == "32") "32位" else "64位",
                gameType = downloadEntity.categoryChinese,
                downloadStatus = downloadEntity.getMetaExtra(Constants.DOWNLOAD_STATUS_IN_CHINESE),
                downloadType = if (downloadEntity.asVGame()) "畅玩下载" else "本地下载"
            )
        }
    }

    private fun trackDownloadSuspendedWindowGuideClick() {
        SensorsBridge.trackDownloadSuspendedWindowGuideClick()
    }

    private fun updateCurrentDownloadEntity(downloadEntity: DownloadEntity) {
        this.currentDownloadEntity = downloadEntity
    }

    /**
     * 是否为当前悬浮窗显示的游戏
     */
    private fun isCurrentDownloadEntity(downloadEntity: DownloadEntity): Boolean {
        return this.currentDownloadEntity == downloadEntity || this.currentDownloadEntity?.gameId == downloadEntity.gameId
    }

    private fun updateDownloadIconAndState(iconUrl: String, downloadState: NDownloadState) {
        iconWindow?.setDownloadIconUrl(iconUrl)
        iconWindow?.setDownloadState(downloadState)
    }

    private fun onDownloadChanged(downloadEntity: DownloadEntity) {
        val status = downloadEntity.status

        if (isCurrentDownloadEntity(downloadEntity) && (status == DownloadStatus.done || status == DownloadStatus.cancel || status == DownloadStatus.delete)) {
            currentActivityRef?.get()?.let { dismiss() }
            return
        }

        if (status == DownloadStatus.downloading && isCurrentDownloadEntity(downloadEntity)) {
            iconWindow?.setDownloadState(NDownloadState.Downloading(downloadEntity.percent.toInt()))
            return
        }

        if (status == DownloadStatus.pause && isCurrentDownloadEntity(downloadEntity)) {
            iconWindow?.setDownloadState(NDownloadState.Pause)
            return
        }
    }

    override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) = Unit

    override fun onActivityStarted(activity: Activity) {
        if (!NDownloadSuspendWindowHelper.isRequestingPermission()) return

        if (NDownloadSuspendWindowHelper.canDrawOverLayer(activity)) {
            onGrantDrawOverlayPermissionListener?.onGrantDrawOverlayPermission()
            dismiss()
        }

        NDownloadSuspendWindowHelper.doneRequestingPermission()
    }

    override fun onActivityResumed(activity: Activity) = Unit

    override fun onActivityPaused(activity: Activity) = Unit

    override fun onActivityStopped(activity: Activity) = Unit

    override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) = Unit

    override fun onActivityDestroyed(activity: Activity) {
        if (activity == currentActivityRef?.get()) {
            dismiss()
        }
    }

    interface OnGrantDrawOverlayPermissionListener {
        fun onGrantDrawOverlayPermission()
    }

}