package com.aiosman.ravenow.data

import com.aiosman.ravenow.data.api.ApiClient
import com.aiosman.ravenow.data.api.CreateRoomRuleRequestBody
import com.aiosman.ravenow.data.api.UpdateRoomRuleRequestBody
import com.aiosman.ravenow.data.api.RoomRuleQuota
import com.aiosman.ravenow.data.api.RoomRule
import com.aiosman.ravenow.data.api.RoomRuleCreator
import com.aiosman.ravenow.entity.AddAgentToRoomFailedItemEntity
import com.aiosman.ravenow.entity.AddAgentToRoomItemEntity
import com.aiosman.ravenow.entity.AddAgentToRoomResultEntity
import com.aiosman.ravenow.entity.AddUserToRoomFailedItemEntity
import com.aiosman.ravenow.entity.AddUserToRoomItemEntity
import com.aiosman.ravenow.entity.AddUserToRoomResultEntity
import com.aiosman.ravenow.entity.CreatorEntity
import com.aiosman.ravenow.entity.RemoveAgentFromRoomFailedItemEntity
import com.aiosman.ravenow.entity.RemoveAgentFromRoomItemEntity
import com.aiosman.ravenow.entity.RemoveAgentFromRoomResultEntity
import com.aiosman.ravenow.entity.RemoveUserFromRoomFailedItemEntity
import com.aiosman.ravenow.entity.RemoveUserFromRoomItemEntity
import com.aiosman.ravenow.entity.RemoveUserFromRoomResultEntity
import com.aiosman.ravenow.entity.RoomEntity
import com.aiosman.ravenow.entity.RoomRuleEntity
import com.aiosman.ravenow.entity.RoomRuleCreatorEntity
import com.aiosman.ravenow.entity.RoomRuleQuotaEntity
import com.aiosman.ravenow.entity.UsersEntity
import com.google.gson.annotations.SerializedName

/**
 * 房间内的智能体信息（PromptTemplate）
 */
data class PromptTemplate(
    @SerializedName("id")
    val id: Int,
    @SerializedName("openId")
    val openId: String,
    @SerializedName("title")
    val title: String,
    @SerializedName("desc")
    val desc: String,
    @SerializedName("avatar")
    val avatar: String
)

data class Room(
    @SerializedName("id")
    val id: Int,
    @SerializedName("name")
    val name: String,
    @SerializedName("description")
    val description: String,
    @SerializedName("trtcRoomId")
    val trtcRoomId: String,
    @SerializedName("trtcType")
    val trtcType: String,
    @SerializedName("cover")
    val cover: String,
    @SerializedName("avatar")
    val avatar: String,
    @SerializedName("recommendBanner")
    val recommendBanner: String,
    @SerializedName("isRecommended")
    val isRecommended: Boolean,
    @SerializedName("allowInHot")
    val allowInHot: Boolean,
    @SerializedName("creator")
    val creator: Creator,
    @SerializedName("userCount")
    val userCount: Int,
    @SerializedName("totalMemberCount")
    val totalMemberCount: Int? = null,
    @SerializedName("maxMemberLimit")
    val maxMemberLimit: Int,
    @SerializedName("maxTotal")
    val maxTotal: Int? = null,
    @SerializedName("systemMaxTotal")
    val systemMaxTotal: Int? = null,
    @SerializedName("canJoin")
    val canJoin: Boolean,
    @SerializedName("canJoinCode")
    val canJoinCode: Int,
    @SerializedName("privateFeePaid")
    val privateFeePaid: Boolean? = null,
    @SerializedName("prompts")
    val prompts: List<PromptTemplate>? = null,
    @SerializedName("createdAt")
    val createdAt: String? = null,
    @SerializedName("updatedAt")
    val updatedAt: String? = null,
    @SerializedName("users")
    val users: List<Users>

    ) {
    fun toRoomtEntity(): RoomEntity {
        return RoomEntity(
        id= id,
        name = name,
        description = description ,
        trtcRoomId = trtcRoomId,
        trtcType = trtcType,
        cover =  cover,
        avatar = avatar,
        recommendBanner = recommendBanner,
        isRecommended = isRecommended,
        allowInHot = allowInHot,
        creator = creator.toCreatorEntity(),
        userCount = userCount,
        totalMemberCount = totalMemberCount,
        maxMemberLimit = maxMemberLimit,
        maxTotal = maxTotal,
        systemMaxTotal = systemMaxTotal,
        canJoin = canJoin,
        canJoinCode = canJoinCode,
        privateFeePaid = privateFeePaid ?: false,
        prompts = prompts?.map { 
            com.aiosman.ravenow.entity.PromptTemplateEntity(
                id = it.id,
                openId = it.openId,
                title = it.title,
                desc = it.desc,
                avatar = it.avatar
            )
        } ?: emptyList(),
        createdAt = createdAt,
        updatedAt = updatedAt,
            users = users.map { it.toUsersEntity() }
        )
    }
}


data class Creator(
    @SerializedName("id")
    val id: Int,
    @SerializedName("userId")
    val userId: String,
    @SerializedName("trtcUserId")
    val trtcUserId: String? = null,
    @SerializedName("profile")
    val profile: Profile
){
    fun toCreatorEntity(): CreatorEntity {
        return CreatorEntity(
            id = id,
            userId = userId,
            trtcUserId = trtcUserId ?: "",
            profile = profile.toProfileEntity()
        )
    }
}

data class Users(
    @SerializedName("id")
    val id: Int,
    @SerializedName("userId")
    val userId: String,
    @SerializedName("trtcUserId")
    val trtcUserId: String? = null,
    @SerializedName("profile")
    val profile: Profile
){
    fun toUsersEntity(): UsersEntity {
        return UsersEntity(
            id = id,
            userId = userId,
            profile = profile.toProfileEntity()
        )
    }
}

/**
 * 房间规则相关服务
 */
interface RoomService {
    /**
     * 创建房间规则
     * @param rule 规则内容，不能为空
     * @param roomId 房间ID，与 trtcId 二选一
     * @param trtcId TRTC房间ID，与 roomId 二选一
     * @throws ServiceException 创建失败时抛出异常
     */
    suspend fun createRoomRule(
        rule: String,
        roomId: Int? = null,
        trtcId: String? = null
    )

    /**
     * 修改房间规则
     * @param id 规则ID
     * @param rule 新的规则内容，不能为空
     * @throws ServiceException 修改失败时抛出异常
     */
    suspend fun updateRoomRule(
        id: Int,
        rule: String
    )

    /**
     * 删除房间规则
     * @param id 规则ID
     * @throws ServiceException 删除失败时抛出异常
     */
    suspend fun deleteRoomRule(id: Int)

    /**
     * 查询房间规则列表
     * @param roomId 房间ID，与 trtcId 二选一
     * @param trtcId TRTC房间ID，与 roomId 二选一
     * @param page 页码，默认 1
     * @param pageSize 每页数量，默认 10
     * @return 规则列表响应，包含分页信息和规则列表
     * @throws ServiceException 查询失败时抛出异常
     */
    suspend fun getRoomRuleList(
        roomId: Int? = null,
        trtcId: String? = null,
        page: Int = 1,
        pageSize: Int = 10
    ): ListContainer<RoomRuleEntity>

    /**
     * 查询规则配额使用情况
     * @param roomId 房间ID，与 trtcId 二选一
     * @param trtcId TRTC房间ID，与 roomId 二选一
     * @return 规则配额信息
     * @throws ServiceException 查询失败时抛出异常
     */
    suspend fun getRoomRuleQuota(
        roomId: Int? = null,
        trtcId: String? = null
    ): RoomRuleQuotaEntity

    // ========== Room Member Management ==========

    /**
     * 添加用户到房间
     * 
     * @param roomId 房间ID，与 trtcId 二选一
     * @param trtcId TRTC群组ID，与 roomId 二选一
     * @param openIds 要添加的用户OpenID列表
     * @return 添加结果实体
     * @throws ServiceException 添加失败时抛出异常
     */
    suspend fun addUserToRoom(
        roomId: Int? = null,
        trtcId: String? = null,
        openIds: List<String>
    ): AddUserToRoomResultEntity

    /**
     * 添加智能体到房间
     * 
     * @param roomId 房间ID，与 trtcId 二选一
     * @param trtcId TRTC群组ID，与 roomId 二选一
     * @param agentOpenIds 要添加的智能体OpenID列表
     * @return 添加结果实体
     * @throws ServiceException 添加失败时抛出异常
     */
    suspend fun addAgentToRoom(
        roomId: Int? = null,
        trtcId: String? = null,
        agentOpenIds: List<String>
    ): AddAgentToRoomResultEntity

    /**
     * 从房间移除智能体
     * 
     * @param roomId 房间ID，与 trtcId 二选一
     * @param trtcId TRTC群组ID，与 roomId 二选一
     * @param agentOpenIds 要移除的智能体OpenID列表
     * @return 移除结果实体
     * @throws ServiceException 移除失败时抛出异常
     */
    suspend fun removeAgentFromRoom(
        roomId: Int? = null,
        trtcId: String? = null,
        agentOpenIds: List<String>
    ): RemoveAgentFromRoomResultEntity

    /**
     * 从房间移除用户
     * 
     * @param roomId 房间ID，与 trtcId 二选一
     * @param trtcId TRTC群组ID，与 roomId 二选一
     * @param userIds 要移除的用户ID列表（OpenID）
     * @return 移除结果实体
     * @throws ServiceException 移除失败时抛出异常
     */
    suspend fun removeUserFromRoom(
        roomId: Int? = null,
        trtcId: String? = null,
        userIds: List<String>
    ): RemoveUserFromRoomResultEntity
}

/**
 * 房间规则服务实现类
 */
class RoomServiceImpl : RoomService {
    override suspend fun createRoomRule(
        rule: String,
        roomId: Int?,
        trtcId: String?
    ) {
        val resp = ApiClient.api.createRoomRule(
            CreateRoomRuleRequestBody(
                rule = rule,
                roomId = roomId,
                trtcId = trtcId
            )
        )
        if (!resp.isSuccessful) {
            throw ServiceException("创建房间规则失败")
        }
    }

    override suspend fun updateRoomRule(
        id: Int,
        rule: String
    ) {
        val resp = ApiClient.api.updateRoomRule(
            UpdateRoomRuleRequestBody(
                id = id,
                rule = rule
            )
        )
        if (!resp.isSuccessful) {
            throw ServiceException("修改房间规则失败")
        }
    }

    override suspend fun deleteRoomRule(id: Int) {
        val resp = ApiClient.api.deleteRoomRule(id)
        if (!resp.isSuccessful) {
            throw ServiceException("删除房间规则失败")
        }
    }

    override suspend fun getRoomRuleList(
        roomId: Int?,
        trtcId: String?,
        page: Int,
        pageSize: Int
    ): ListContainer<RoomRuleEntity> {
        val resp = ApiClient.api.getRoomRuleList(
            roomId = roomId,
            trtcId = trtcId,
            page = page,
            pageSize = pageSize
        )
        val body = resp.body() ?: throw ServiceException("获取房间规则列表失败")
        
        return ListContainer(
            list = body.list.map { it.toRoomRuleEntity() },
            page = body.page,
            total = body.total,
            pageSize = body.pageSize
        )
    }

    override suspend fun getRoomRuleQuota(
        roomId: Int?,
        trtcId: String?
    ): RoomRuleQuotaEntity {
        val resp = ApiClient.api.getRoomRuleQuota(
            roomId = roomId,
            trtcId = trtcId
        )
        val body = resp.body() ?: throw ServiceException("获取规则配额信息失败")
        val data = body.data ?: throw ServiceException("规则配额数据为空")
        
        return data.toRoomRuleQuotaEntity()
    }

    override suspend fun addUserToRoom(
        roomId: Int?,
        trtcId: String?,
        openIds: List<String>
    ): AddUserToRoomResultEntity {
        val resp = ApiClient.api.addUserToRoom(
            com.aiosman.ravenow.data.api.AddUserToRoomRequestBody(
                roomId = roomId,
                trtcId = trtcId,
                openIds = openIds
            )
        )
        val body = resp.body() ?: throw ServiceException("添加用户到房间失败")
        val data = body.data ?: throw ServiceException("添加用户响应数据为空")
        
        return data.result.toAddUserToRoomResultEntity()
    }

    override suspend fun addAgentToRoom(
        roomId: Int?,
        trtcId: String?,
        agentOpenIds: List<String>
    ): AddAgentToRoomResultEntity {
        val resp = ApiClient.api.addAgentToRoom(
            com.aiosman.ravenow.data.api.AddAgentToRoomRequestBody(
                roomId = roomId,
                trtcId = trtcId,
                agentOpenIds = agentOpenIds
            )
        )
        val body = resp.body() ?: throw ServiceException("添加智能体到房间失败")
        val data = body.data ?: throw ServiceException("添加智能体响应数据为空")
        
        return data.result.toAddAgentToRoomResultEntity()
    }

    override suspend fun removeAgentFromRoom(
        roomId: Int?,
        trtcId: String?,
        agentOpenIds: List<String>
    ): RemoveAgentFromRoomResultEntity {
        val resp = ApiClient.api.removeAgentFromRoom(
            com.aiosman.ravenow.data.api.RemoveAgentFromRoomRequestBody(
                roomId = roomId,
                trtcId = trtcId,
                agentOpenIds = agentOpenIds
            )
        )
        val body = resp.body() ?: throw ServiceException("从房间移除智能体失败")
        val data = body.data ?: throw ServiceException("移除智能体响应数据为空")
        
        return data.toRemoveAgentFromRoomResultEntity()
    }

    override suspend fun removeUserFromRoom(
        roomId: Int?,
        trtcId: String?,
        userIds: List<String>
    ): RemoveUserFromRoomResultEntity {
        val resp = ApiClient.api.removeUserFromRoom(
            com.aiosman.ravenow.data.api.RemoveUserFromRoomRequestBody(
                roomId = roomId,
                trtcId = trtcId,
                userIds = userIds
            )
        )
        val body = resp.body() ?: throw ServiceException("从房间移除用户失败")
        val data = body.data ?: throw ServiceException("移除用户响应数据为空")
        
        return data.toRemoveUserFromRoomResultEntity()
    }
}

/**
 * RoomRule 扩展函数，转换为 RoomRuleEntity
 */
fun RoomRule.toRoomRuleEntity(): RoomRuleEntity {
    return RoomRuleEntity(
        id = id,
        rule = rule,
        creator = creator?.toRoomRuleCreatorEntity(),
        creatorType = creatorType,
        roomId = roomId,
        createdAt = createdAt,
        updatedAt = updatedAt
    )
}

/**
 * RoomRuleCreator 扩展函数，转换为 RoomRuleCreatorEntity
 */
fun RoomRuleCreator.toRoomRuleCreatorEntity(): RoomRuleCreatorEntity {
    return RoomRuleCreatorEntity(
        id = id,
        nickname = nickname,
        avatar = avatar,
        avatarMedium = avatarMedium,
        avatarLarge = avatarLarge,
        avatarDirectUrl = avatarDirectUrl,
        avatarMediumDirectUrl = avatarMediumDirectUrl,
        avatarLargeDirectUrl = avatarLargeDirectUrl
    )
}

/**
 * RoomRuleQuota 扩展函数，转换为 RoomRuleQuotaEntity
 */
fun RoomRuleQuota.toRoomRuleQuotaEntity(): RoomRuleQuotaEntity {
    return RoomRuleQuotaEntity(
        baseMaxCount = baseMaxCount,
        purchasedCount = purchasedCount,
        totalMaxCount = totalMaxCount,
        currentCount = currentCount,
        remainingCount = remainingCount,
        usagePercent = usagePercent
    )
}

// ========== Room Member Management 扩展函数 ==========

/**
 * AddUserToRoomResult 扩展函数，转换为 AddUserToRoomResultEntity
 */
fun com.aiosman.ravenow.data.api.AddUserToRoomResult.toAddUserToRoomResultEntity(): AddUserToRoomResultEntity {
    return AddUserToRoomResultEntity(
        totalCount = totalCount,
        successCount = successCount,
        failedCount = failedCount,
        skippedCount = skippedCount,
        successItems = successItems.map { it.toAddUserToRoomItemEntity() },
        failedItems = failedItems.map { it.toAddUserToRoomFailedItemEntity() },
        skippedItems = skippedItems.map { it.toAddUserToRoomItemEntity() }
    )
}

fun com.aiosman.ravenow.data.api.AddUserToRoomItem.toAddUserToRoomItemEntity(): AddUserToRoomItemEntity {
    return AddUserToRoomItemEntity(
        userId = userId,
        type = type
    )
}

fun com.aiosman.ravenow.data.api.AddUserToRoomFailedItem.toAddUserToRoomFailedItemEntity(): AddUserToRoomFailedItemEntity {
    return AddUserToRoomFailedItemEntity(
        userId = userId,
        type = type,
        error = error
    )
}

/**
 * AddAgentToRoomResult 扩展函数，转换为 AddAgentToRoomResultEntity
 */
fun com.aiosman.ravenow.data.api.AddAgentToRoomResult.toAddAgentToRoomResultEntity(): AddAgentToRoomResultEntity {
    return AddAgentToRoomResultEntity(
        totalCount = totalCount,
        successCount = successCount,
        failedCount = failedCount,
        skippedCount = skippedCount,
        successItems = successItems.map { it.toAddAgentToRoomItemEntity() },
        failedItems = failedItems.map { it.toAddAgentToRoomFailedItemEntity() },
        skippedItems = skippedItems.map { it.toAddAgentToRoomItemEntity() }
    )
}

fun com.aiosman.ravenow.data.api.AddAgentToRoomItem.toAddAgentToRoomItemEntity(): AddAgentToRoomItemEntity {
    return AddAgentToRoomItemEntity(
        agentOpenId = agentOpenId,
        type = type
    )
}

fun com.aiosman.ravenow.data.api.AddAgentToRoomFailedItem.toAddAgentToRoomFailedItemEntity(): AddAgentToRoomFailedItemEntity {
    return AddAgentToRoomFailedItemEntity(
        agentOpenId = agentOpenId,
        type = type,
        error = error
    )
}

/**
 * RemoveAgentFromRoomResult 扩展函数，转换为 RemoveAgentFromRoomResultEntity
 */
fun com.aiosman.ravenow.data.api.RemoveAgentFromRoomResult.toRemoveAgentFromRoomResultEntity(): RemoveAgentFromRoomResultEntity {
    return RemoveAgentFromRoomResultEntity(
        totalCount = totalCount,
        successCount = successCount,
        failedCount = failedCount,
        skippedCount = skippedCount,
        successItems = successItems.map { it.toRemoveAgentFromRoomItemEntity() },
        failedItems = failedItems.map { it.toRemoveAgentFromRoomFailedItemEntity() },
        skippedItems = skippedItems.map { it.toRemoveAgentFromRoomItemEntity() }
    )
}

fun com.aiosman.ravenow.data.api.RemoveAgentFromRoomItem.toRemoveAgentFromRoomItemEntity(): RemoveAgentFromRoomItemEntity {
    return RemoveAgentFromRoomItemEntity(
        agentOpenId = agentOpenId,
        type = type
    )
}

fun com.aiosman.ravenow.data.api.RemoveAgentFromRoomFailedItem.toRemoveAgentFromRoomFailedItemEntity(): RemoveAgentFromRoomFailedItemEntity {
    return RemoveAgentFromRoomFailedItemEntity(
        agentOpenId = agentOpenId,
        type = type,
        error = error
    )
}

/**
 * RemoveUserFromRoomResult 扩展函数，转换为 RemoveUserFromRoomResultEntity
 */
fun com.aiosman.ravenow.data.api.RemoveUserFromRoomResult.toRemoveUserFromRoomResultEntity(): RemoveUserFromRoomResultEntity {
    return RemoveUserFromRoomResultEntity(
        totalCount = totalCount,
        successCount = successCount,
        failedCount = failedCount,
        skippedCount = skippedCount,
        successItems = successItems.map { it.toRemoveUserFromRoomItemEntity() },
        failedItems = failedItems.map { it.toRemoveUserFromRoomFailedItemEntity() },
        skippedItems = skippedItems.map { it.toRemoveUserFromRoomItemEntity() }
    )
}

fun com.aiosman.ravenow.data.api.RemoveUserFromRoomItem.toRemoveUserFromRoomItemEntity(): RemoveUserFromRoomItemEntity {
    return RemoveUserFromRoomItemEntity(
        userId = userId,
        type = type
    )
}

fun com.aiosman.ravenow.data.api.RemoveUserFromRoomFailedItem.toRemoveUserFromRoomFailedItemEntity(): RemoveUserFromRoomFailedItemEntity {
    return RemoveUserFromRoomFailedItemEntity(
        userId = userId,
        type = type,
        error = error
    )
}




