package com.gh.gamecenter.forum.home.follow.model

import com.gh.common.util.LibaoUtils
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.UrlFilterUtils
import com.gh.gamecenter.entity.FollowCommonContentCollection
import com.gh.gamecenter.entity.FollowDynamicEntity
import com.gh.gamecenter.entity.FollowDynamicEntity.Companion.FOLLOW_UPDATE_TYPE_ARTICLE
import com.gh.gamecenter.entity.FollowDynamicEntity.Companion.FOLLOW_UPDATE_TYPE_LIBAO
import com.gh.gamecenter.entity.FollowDynamicEntity.Companion.FOLLOW_UPDATE_TYPE_LIBAO_EXCHANGE
import com.gh.gamecenter.entity.FollowDynamicEntity.Companion.FOLLOW_UPDATE_TYPE_USER_POST
import com.gh.gamecenter.entity.FollowUserEntity
import com.gh.gamecenter.feature.entity.LibaoEntity
import com.gh.gamecenter.forum.home.follow.*
import com.gh.gamecenter.home.custom.model.CustomPageData
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_BANNER
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_VERTICAL_CARD
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMMON_CONTENT_COLLECTION_LAYOUT_VERTICAL_IMAGE_TEXT
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.retrofit.service.ApiService
import com.halo.assistant.HaloApp
import io.reactivex.Single

class FollowRepository(
    private val apiService: ApiService,
    private val newApiService: ApiService
) {

    private var hasFollowUser = false

    private val version: String
        get() = PackageUtils.getGhVersionName()

    private val channel: String
        get() = HaloApp.getInstance().channel

    fun loadHomeData(isLogin: Boolean, type: String, pageNo: Int) =
        if (isLogin) {
            loadFollowedUsers()
                .flatMap { users ->
                    if (users.isEmpty()) {
                        hasFollowUser = false
                        // 默认推荐
                        loadFollowRecommend(pageNo)
                            .map {
                                listOf(FollowUserItem(true, listOf())) + it
                            }
                    } else {
                        // 关注动态
                        hasFollowUser = true
                        loadFollowUpdates(type, pageNo)
                            .map {
                                listOf(FollowUserItem(true, users)) + it
                            }
                    }
                }
        } else {
            loadFollowRecommend(pageNo)
                .map {
                    listOf(FollowUserItem(false, listOf())) + it
                }
        }

    fun loadMore(type: String, pageNo: Int) =
        if (hasFollowUser) {
            loadFollowUpdates(type, pageNo)
        } else {
            loadFollowRecommend(pageNo)
        }

    fun loadFollowedUsers(): Single<List<FollowUserEntity>> {
        return newApiService.getMyFollowedUsers(
            UserManager.getInstance().userId,
            PackageUtils.getGhVersionName(),
            HaloApp.getInstance().channel,
            1,
            true,
            mapOf("page_size" to 20)
        ).onErrorReturnItem(listOf())
    }

    private fun loadFollowUpdates(type: String, pageNo: Int): Single<List<FollowItem>> =
        newApiService.getFollowUpdates(
            UserManager.getInstance().userId,
            type,
            pageNo,
            PackageUtils.getGhVersionName(),
            HaloApp.getInstance().channel
        )
            .onErrorReturnItem(listOf())
            .map(::transformFollowUpdatesToItemData)

    fun loadFollowRecommend(pageNo: Int): Single<List<FollowItem>> =
        if (pageNo == 1) {
            loadRecommendUsers().zipWith(
                loadFollowCommonCollection(pageNo)
            ) { user, commonCollections ->
                val data = arrayListOf<FollowItem>()
                if (user.data.isNotEmpty()) {
                    data.add(user)
                }
                data.addAll(commonCollections)
                data
            }
        } else {
            Single.just(listOf())
        }

    private fun loadRecommendUsers(): Single<FollowRecommendUsersItem> =
        newApiService.getRecommendUser(version, channel)
            .onErrorReturnItem(listOf())
            .map(::FollowRecommendUsersItem)


    private fun loadFollowCommonCollection(pageNo: Int): Single<List<FollowItem>> =
        newApiService.getFollowCommonCollection(version, channel, pageNo)
            .onErrorReturnItem(listOf())
            .map { components ->
                val data = arrayListOf<FollowItem>()
                components.forEach {
                    val layout = it.linkCommonCollection?.layout
                    if (layout == COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_BANNER
                        || layout == COMMON_CONTENT_COLLECTION_LAYOUT_DOUBLE_ROW_VERTICAL_CARD
                        || layout == COMMON_CONTENT_COLLECTION_LAYOUT_VERTICAL_IMAGE_TEXT
                    ) {
                        data.addAll(convertSplitCommonContentCollection(it))
                    } else {
                        // data.title 为后台配置的板块title
                        it.linkCommonCollection.name = it.title
                        data.add(
                            FollowCommonCollectionItem(it)
                        )
                    }
                }
                data
            }

    private fun convertSplitCommonContentCollection(item: FollowCommonContentCollection): List<FollowSplitCommonContentCollectionItem> {
        val linkCommonCollection = item.linkCommonCollection
        // data.title 为后台配置的板块title
        linkCommonCollection.name = item.title
        val data = linkCommonCollection.data
        val items = arrayListOf<FollowSplitCommonContentCollectionItem>()
        (data.indices step 2).forEach { left ->
            items.add(
                FollowSplitCommonContentCollectionItem(
                    linkCommonCollection,
                    left
                )
            )
        }
        return items
    }

    fun followUser(userId: String, isFollow: Boolean) =
        if (isFollow) {
            apiService.postFollowing(userId)
        } else {
            apiService.deleteFollowing(userId)
        }

    fun postArticleVisit(articleId: String) =
        apiService.postArticleVisit(articleId)

    companion object {

        const val FOLLOW_UPDATE_TYPE_USER = "user"
        const val FOLLOW_UPDATE_TYPE_GAME = "game"

        fun transformFollowUpdatesToItemData(updates: List<FollowDynamicEntity>): List<FollowItem> {
            val data = arrayListOf<FollowItem>()
            updates.forEach {
                when (it.type) {
                    FOLLOW_UPDATE_TYPE_LIBAO -> {
                        if (it.libao != null) {
                            FollowGiftPackItem(it.libao, it.time)
                        } else {
                            null
                        }
                    }

                    FOLLOW_UPDATE_TYPE_LIBAO_EXCHANGE -> {
                        if (it.libaoExchange != null) {
                            FollowGiftPackItem(it.libaoExchange, it.time)
                        } else {
                            null
                        }
                    }

                    FOLLOW_UPDATE_TYPE_ARTICLE -> it.article?.let(::FollowArticleItem)

                    FOLLOW_UPDATE_TYPE_USER_POST -> it.userPost?.let(::FollowPostCardItem)

                    else -> null
                }?.let(data::add)
            }
            return data
        }

        fun newInstance() = FollowRepository(RetrofitManager.getInstance().api, RetrofitManager.getInstance().newApi)
    }
}