package com.adealink.weparty.playmate.manager

import com.adealink.frame.base.CommonDataNullError
import com.adealink.frame.base.CommonParamError
import com.adealink.frame.base.Rlt
import com.adealink.frame.base.fastLazy
import com.adealink.frame.frame.BaseFrame
import com.adealink.frame.locale.language.data.Language
import com.adealink.frame.locale.language.listener.ILanguageListener
import com.adealink.frame.log.Log
import com.adealink.frame.storage.cache.TimeoutLruCache
import com.adealink.weparty.App
import com.adealink.weparty.module.playmate.data.PlaymateCategoryConditionData
import com.adealink.weparty.module.playmate.data.PlaymateCategoryData
import com.adealink.weparty.module.playmate.data.TAG_PLAYMATE_MANAGER
import com.adealink.weparty.module.playmate.data.UserPlaymateCategoryData
import com.adealink.weparty.playmate.data.UserPlaymateCategoryReq
import com.adealink.weparty.playmate.datasource.remote.PlaymateHttpService


val playmateManager by fastLazy { PlaymateManager() }

class PlaymateManager : BaseFrame<IPlaymateListener>(), IPlaymateManager, ILanguageListener {

    private val playmateHttpService by lazy {
        App.instance.networkService.getHttpService(PlaymateHttpService::class.java)
    }

    private val userPlaymateCategoryCache by lazy {
        TimeoutLruCache<String, List<UserPlaymateCategoryData>>(
            500,
            10 * 60 * 1000
        ) //最多缓存5000个，缓存时长10分钟
    }

    private var allCategoryCacheTs = 0L
    private var allCategory = listOf<PlaymateCategoryData>()

    private var allCategoryConditionCacheTs = 0L
    private var allCategoryCondition = mapOf<String, PlaymateCategoryConditionData>()

    init {
        App.instance.languageManager.addListener(this)
    }


    override suspend fun pullAllCategory(): Rlt<List<PlaymateCategoryData>> {
        //缓存时间1h ( 3_600_00 )
        if (allCategory.isNotEmpty() && (System.currentTimeMillis() - allCategoryCacheTs < 3_600_00)) {
            return Rlt.Success(allCategory)
        }
        val rlt = playmateHttpService.getAllCategory()
        when (rlt) {
            is Rlt.Failed -> {
                return rlt
            }

            is Rlt.Success -> {
                val list = rlt.data.data?.list
                if (list == null) {
                    //保持原样不更新
                    return Rlt.Failed(CommonDataNullError())
                }
                allCategory = list
                allCategoryCacheTs = System.currentTimeMillis()
                return Rlt.Success(allCategory)
            }
        }
    }

    override suspend fun pullAllCategoryCondition(): Map<String, PlaymateCategoryConditionData> {
        //缓存时间1h ( 3_600_00 )
        if (allCategoryCondition.isNotEmpty() && (System.currentTimeMillis() - allCategoryConditionCacheTs < 3_600_00)) {
            return allCategoryCondition
        }
        val rlt = playmateHttpService.getAllCategoryCondition()
        when (rlt) {
            is Rlt.Failed -> {
                return emptyMap()
            }

            is Rlt.Success -> {
                val list = rlt.data.data?.list ?: emptyList()
                val map = mutableMapOf<String, PlaymateCategoryConditionData>()
                for (data in list) {
                    map[data.code] = data
                }
                allCategoryCondition = map
                allCategoryConditionCacheTs = System.currentTimeMillis()
                return allCategoryCondition
            }
        }
    }


    override suspend fun getUserPlaymateCategory(
        uid: String,
        cache: Boolean
    ): Rlt<List<UserPlaymateCategoryData>> {
        if (uid.isEmpty()) {
            return Rlt.Failed(CommonParamError("uid($uid) is invalid"))
        }
        if (cache) {
            val data = userPlaymateCategoryCache[uid]
            if (data != null) {
                return Rlt.Success(data)
            }
        }

        Log.d(TAG_PLAYMATE_MANAGER, "PlaymateManager.getPlaymateCategory, uid:${uid}")
        val rlt = playmateHttpService.getUserPlaymateCategory(UserPlaymateCategoryReq(uid))
        return when (rlt) {
            is Rlt.Failed -> {
                rlt
            }

            is Rlt.Success -> {
                val data = rlt.data.data ?: return Rlt.Failed(CommonDataNullError())
                updateUserPlaymateCategory(uid, data.list)
                return Rlt.Success(data.list)
            }
        }
    }

    private fun updateUserPlaymateCategory(
        uid: String,
        categoryList: List<UserPlaymateCategoryData>
    ) {
        userPlaymateCategoryCache.put(uid, categoryList)
    }

    override fun onLanguageChanged(currentLanguage: Language) {
        allCategoryCacheTs = 0
        allCategory = emptyList()
    }

}