package com.aiosman.ravenow.entity

import android.util.Log
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.aiosman.ravenow.data.ListContainer
import com.aiosman.ravenow.data.Room
import com.aiosman.ravenow.data.ServiceException
import com.aiosman.ravenow.data.api.ApiClient
import java.io.IOException

/**
 * 群聊房间
 */

/**
 * 房间内的智能体信息实体
 */
data class PromptTemplateEntity(
    val id: Int,
    val openId: String,
    val title: String,
    val desc: String,
    val avatar: String
)

data class RoomEntity(
    val id: Int,
    val name: String,
    val description: String,
    val trtcRoomId: String,
    val trtcType: String,
    val cover: String,
    val avatar: String,
    val recommendBanner: String,
    val isRecommended: Boolean,
    val allowInHot: Boolean,
    val creator: CreatorEntity,
    val userCount: Int,
    val totalMemberCount: Int? = null,
    val maxMemberLimit: Int,
    val maxTotal: Int? = null,
    val systemMaxTotal: Int? = null,
    val canJoin: Boolean,
    val canJoinCode: Int,
    val privateFeePaid: Boolean = false,
    val prompts: List<PromptTemplateEntity> = emptyList(),
    val createdAt: String? = null,
    val updatedAt: String? = null,
    val users: List<UsersEntity>,
)

data class CreatorEntity(
    val id: Int,
    val userId: String,
    val trtcUserId: String,
    val profile: ProfileEntity
)

data class UsersEntity(
    val id: Int,
    val userId: String,
    val profile: ProfileEntity
)

data class ProfileEntity(
    val id: Int,
    val username: String,
    val nickname: String,
    val avatar: String,
    val banner: String,
    val bio: String,
    val trtcUserId: String,
    val chatAIId: String,
    val aiAccount: Boolean,
)

/**
 * 房间规则创建者信息
 */
data class RoomRuleCreatorEntity(
    val id: Int,
    val nickname: String,
    val avatar: String,
    val avatarMedium: String? = null,
    val avatarLarge: String? = null,
    val avatarDirectUrl: String? = null,
    val avatarMediumDirectUrl: String? = null,
    val avatarLargeDirectUrl: String? = null
)

/**
 * 房间规则详情
 */
data class RoomRuleEntity(
    val id: Int,
    val rule: String,
    val creator: RoomRuleCreatorEntity?,
    val creatorType: String,
    val roomId: Int,
    val createdAt: String,
    val updatedAt: String
)

/**
 * 房间规则配额信息
 */
data class RoomRuleQuotaEntity(
    val baseMaxCount: Int,
    val purchasedCount: Int,
    val totalMaxCount: Int,
    val currentCount: Int,
    val remainingCount: Int,
    val usagePercent: Double
)

// ========== Room Member Management 实体类 ==========

/**
 * 添加用户成功项目
 */
data class AddUserToRoomItemEntity(
    val userId: String,
    val type: String
)

/**
 * 添加用户失败项目
 */
data class AddUserToRoomFailedItemEntity(
    val userId: String,
    val type: String,
    val error: String
)

/**
 * 添加用户到房间的结果
 */
data class AddUserToRoomResultEntity(
    val totalCount: Int,
    val successCount: Int,
    val failedCount: Int,
    val skippedCount: Int,
    val successItems: List<AddUserToRoomItemEntity>,
    val failedItems: List<AddUserToRoomFailedItemEntity>,
    val skippedItems: List<AddUserToRoomItemEntity>
)

/**
 * 添加智能体成功项目
 */
data class AddAgentToRoomItemEntity(
    val agentOpenId: String,
    val type: String
)

/**
 * 添加智能体失败项目
 */
data class AddAgentToRoomFailedItemEntity(
    val agentOpenId: String,
    val type: String,
    val error: String
)

/**
 * 添加智能体到房间的结果
 */
data class AddAgentToRoomResultEntity(
    val totalCount: Int,
    val successCount: Int,
    val failedCount: Int,
    val skippedCount: Int,
    val successItems: List<AddAgentToRoomItemEntity>,
    val failedItems: List<AddAgentToRoomFailedItemEntity>,
    val skippedItems: List<AddAgentToRoomItemEntity>
)

/**
 * 移除智能体成功项目
 */
data class RemoveAgentFromRoomItemEntity(
    val agentOpenId: String,
    val type: String
)

/**
 * 移除智能体失败项目
 */
data class RemoveAgentFromRoomFailedItemEntity(
    val agentOpenId: String,
    val type: String,
    val error: String
)

/**
 * 从房间移除智能体的结果
 */
data class RemoveAgentFromRoomResultEntity(
    val totalCount: Int,
    val successCount: Int,
    val failedCount: Int,
    val skippedCount: Int,
    val successItems: List<RemoveAgentFromRoomItemEntity>,
    val failedItems: List<RemoveAgentFromRoomFailedItemEntity>,
    val skippedItems: List<RemoveAgentFromRoomItemEntity>
)

/**
 * 移除用户成功项目
 */
data class RemoveUserFromRoomItemEntity(
    val userId: String,
    val type: String
)

/**
 * 移除用户失败项目
 */
data class RemoveUserFromRoomFailedItemEntity(
    val userId: String,
    val type: String,
    val error: String
)

/**
 * 从房间移除用户的结果
 */
data class RemoveUserFromRoomResultEntity(
    val totalCount: Int,
    val successCount: Int,
    val failedCount: Int,
    val skippedCount: Int,
    val successItems: List<RemoveUserFromRoomItemEntity>,
    val failedItems: List<RemoveUserFromRoomFailedItemEntity>,
    val skippedItems: List<RemoveUserFromRoomItemEntity>
)

class RoomLoader : DataLoader<AgentEntity,AgentLoaderExtraArgs>() {
    override suspend fun fetchData(
        page: Int,
        pageSize: Int,
        extra: AgentLoaderExtraArgs
    ): ListContainer<AgentEntity> {
        val result = ApiClient.api.getAgent(
            page = page,
            pageSize = pageSize,

        )
        val data =  result.body()?.let {
            ListContainer(
                list = it.data.list.map { it.toAgentEntity()},
                total = it.data.total,
                page = page,
                pageSize = pageSize
            )
        }
        if (data == null) {
            throw ServiceException("Failed to get agent")
        }
        return data
    }


}

/**
 * 房间远程数据源
 */
class RoomRemoteDataSource {
    suspend fun searchRooms(
        pageNumber: Int,
        pageSize: Int = 20,
        search: String
    ): ListContainer<RoomEntity>? {
        return try {
            val resp = ApiClient.api.getRooms(
                page = pageNumber,
                pageSize = pageSize,
                search = search,
                roomType = "public" // 搜索时只显示公有房间
            )
            if (!resp.isSuccessful) {
                // API 调用失败，返回 null
                return null
            }
            val body = resp.body() ?: return null
            
            // 安全地转换数据，过滤掉转换失败的项目
            val roomList = body.list.mapNotNull { room ->
                try {
                    room.toRoomtEntity()
                } catch (e: Exception) {
                    // 如果某个房间数据转换失败，记录错误但继续处理其他房间
                    Log.e("RoomRemoteDataSource", "Failed to convert room: ${room.id}", e)
                    null
                }
            }
            
            ListContainer(
                total = body.total,
                page = pageNumber,
                pageSize = pageSize,
                list = roomList
            )
        } catch (e: Exception) {
            // 捕获所有异常，返回 null 让 PagingSource 处理
            Log.e("RoomRemoteDataSource", "searchRooms error", e)
            null
        }
    }
}

/**
 * 房间搜索分页加载器
 */
class RoomSearchPagingSource(
    private val roomRemoteDataSource: RoomRemoteDataSource,
    private val keyword: String,
) : PagingSource<Int, RoomEntity>() {
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, RoomEntity> {
        return try {
            val currentPage = params.key ?: 1
            val rooms = roomRemoteDataSource.searchRooms(
                pageNumber = currentPage,
                pageSize = params.loadSize,
                search = keyword
            )
            if (rooms == null) {
                // API 调用失败，返回空列表
                LoadResult.Page(
                    data = emptyList(),
                    prevKey = if (currentPage == 1) null else currentPage - 1,
                    nextKey = null
                )
            } else {
                LoadResult.Page(
                    data = rooms.list,
                    prevKey = if (currentPage == 1) null else currentPage - 1,
                    nextKey = if (rooms.list.isNotEmpty() && rooms.list.size >= params.loadSize) currentPage + 1 else null
                )
            }
        } catch (exception: Exception) {
            // 捕获所有异常，包括 IOException、ServiceException 等
            LoadResult.Error(exception)
        }
    }

    override fun getRefreshKey(state: PagingState<Int, RoomEntity>): Int? {
        // 更健壮的实现：根据 anchorPosition 计算刷新键
        return state.anchorPosition?.let { anchorPosition ->
            state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
                ?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
        }
    }
}