package com.gh.gamecenter.search

import com.gh.common.constant.Config
import com.gh.common.util.AdHelper
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.dsp.data.GameSubjectDSPRemoteDataSource
import com.gh.gamecenter.entity.SearchSubjectEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.gamedetail.accelerator.AccelerationDataBase
import com.gh.gamecenter.minigame.wechat.WGameSubjectCPMRemoteDataSource
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.retrofit.service.ApiService
import com.halo.assistant.HaloApp
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import java.net.URLEncoder
import java.util.concurrent.TimeUnit

class SearchGameResultRepository(
    private val mApi: ApiService = RetrofitManager.getInstance().api,
    private val mNewApi: ApiService = RetrofitManager.getInstance().newApi,
    private val mWGameSubjectCPMDataSource: WGameSubjectCPMRemoteDataSource = WGameSubjectCPMRemoteDataSource(),
    private val mGameSubjectDSPDataSource: GameSubjectDSPRemoteDataSource = GameSubjectDSPRemoteDataSource(RetrofitManager.getInstance().dspApiService)
) : ISearchGameResultRepository {

    private var currentSearchKey: String? = null

    private var currentMiniGameCPMSearchList: MutableList<GameEntity>? = null

    override fun getSearchGame(
        key: String?,
        page: Int
    ): Observable<List<GameEntity>> {
        // 可能会有特殊字符，需要 encode 处理
        val encodedKey = URLEncoder.encode(key, "utf-8")
        return mApi.getSearchGame(
            Config.API_HOST
                    + "games:search?keyword=" + encodedKey
                    + "&view=digest&page=" + page
                    + "&channel=" + HaloApp.getInstance().channel
                    + "&version=" + BuildConfig.VERSION_NAME
                    + "&AD=" + AdHelper.getIdfaString()
        )
            .map { games ->
                // 获取已加速成功过的区服
                val gameCanSpeed = games.filter { it.canSpeed }
                val gameIds = gameCanSpeed
                    .map { it.id }
                val acctGameList = AccelerationDataBase.instance.accelerationDao().queryAcctGameInfoByGameId(gameIds)
                gameCanSpeed.forEach { game ->
                    game.lastAcctGame = acctGameList.find { game.id == it.gameId }
                }
                games
            }
    }

    override fun getSearchMiniGameCPM(key: String?): Observable<List<GameEntity>> {
        val currentMiniGameCPMSearchList = currentMiniGameCPMSearchList
        if (key == currentSearchKey && currentMiniGameCPMSearchList != null) {
            return Observable.just(currentMiniGameCPMSearchList)
        }
        return mNewApi.getSearchWechatMiniCPMGame(key)
            .timeout(5, TimeUnit.SECONDS)
            .onErrorReturnItem(emptyList())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnNext {
                this.currentSearchKey = key
                this.currentMiniGameCPMSearchList = it
            }
    }

    override fun getSearchSubject(key: String?, page: Int): Observable<List<SearchSubjectEntity>> {
        return mApi.getSearchSubject(key, page)
    }

    override fun getWGameCPMGameList(size: Int,): Single<MutableList<GameEntity>> {
        return mWGameSubjectCPMDataSource.getUserRecommendCPMList(pageSize = size)
    }

    override fun getDspGameList(
        columnType: String,
        showDownload: Boolean,
        size: Int,
    ): Single<List<GameEntity>> {
        return mGameSubjectDSPDataSource.getDspGames(columnType, size)
    }
}