package com.all.pdfreader.pdf.reader.ad

import com.google.android.gms.ads.interstitial.InterstitialAd

class InstAdCacheManager {

    private val mAdCacheDict: MutableMap<AdsInsUtil.AdPlacement, CachedAd> = mutableMapOf()

    // 是否正在加载
    private val loadingSet = mutableSetOf<AdsInsUtil.AdPlacement>()

    // 等待回调的 listener（多个 load 时会加入这里）
    private val pendingListeners =
        mutableMapOf<AdsInsUtil.AdPlacement, MutableList<LoadListener?>>()

    companion object {
        val instance: InstAdCacheManager by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
            InstAdCacheManager()
        }
    }

    /** ============= 加载状态控制 ============= */

    fun isLoading(place: AdsInsUtil.AdPlacement) = loadingSet.contains(place)

    fun markLoading(place: AdsInsUtil.AdPlacement, listener: LoadListener?) {
        loadingSet.add(place)
        addPendingListener(place, listener)
    }

    fun addPendingListener(place: AdsInsUtil.AdPlacement, listener: LoadListener?) {
        if (listener == null) return

        val list = pendingListeners[place] ?: mutableListOf()
        if (!list.contains(listener)) {
            list.add(listener)
        }
        pendingListeners[place] = list
    }


    fun notifySuccess(place: AdsInsUtil.AdPlacement, ad: InterstitialAd) {
        pendingListeners[place]?.forEach { it?.loaded(ad) }
        pendingListeners.remove(place)
        loadingSet.remove(place)
    }

    fun notifyFail(place: AdsInsUtil.AdPlacement, msg: String) {
        pendingListeners[place]?.forEach { it?.loadFailed(msg) }
        pendingListeners.remove(place)
        loadingSet.remove(place)
    }

    /** ============= 广告缓存逻辑 ============= */

    fun setAdCache(place: AdsInsUtil.AdPlacement, adCache: InterstitialAd) {
        mAdCacheDict[place] = CachedAd(adCache)
    }

    fun getAdCache(place: AdsInsUtil.AdPlacement): InterstitialAd? {
        val cached = mAdCacheDict[place]
        return if (cached != null && cached.isValid()) cached.ad
        else {
            mAdCacheDict.remove(place) // 清理过期
            null
        }
    }

    fun remove(place: AdsInsUtil.AdPlacement) {
        mAdCacheDict.remove(place)
    }

    /**
     * 包装广告 + 时间
     */
    data class CachedAd(
        val ad: InterstitialAd,
        val loadedAt: Long = System.currentTimeMillis()
    ) {
        // 广告有效期 1 小时
        fun isValid(): Boolean = System.currentTimeMillis() - loadedAt < 3600_000
    }
}
