package com.aiosman.ravenow.data

import com.aiosman.ravenow.AppStore
import com.aiosman.ravenow.data.api.ApiClient
import com.aiosman.ravenow.data.api.AgentRule
import com.aiosman.ravenow.data.api.AgentRuleListResponse
import com.aiosman.ravenow.data.api.AgentRuleQuota
import com.aiosman.ravenow.data.api.AgentRuleAgent
import com.aiosman.ravenow.data.api.CreateAgentRuleRequestBody
import com.aiosman.ravenow.data.api.InsufficientBalanceError
import com.aiosman.ravenow.data.api.UpdateAgentRuleRequestBody
import com.aiosman.ravenow.entity.AgentEntity
import com.aiosman.ravenow.entity.ProfileEntity
import com.google.gson.Gson
import com.google.gson.annotations.SerializedName

data class Agent(
    /*@SerializedName("author")
    val author: String,*/
    @SerializedName("avatar")
    val avatar: String,
    @SerializedName("breakMode")
    val breakMode: Boolean,
    @SerializedName("createdAt")
    val createdAt: String,
    @SerializedName("desc")
    val desc: String,
    @SerializedName("id")
    val id: Int,
    @SerializedName("isPublic")
    val isPublic: Boolean,
    @SerializedName("openId")
    val openId: String,
    @SerializedName("title")
    val title: String,
    @SerializedName("updatedAt")
    val updatedAt: String,
    @SerializedName("useCount")
    val useCount: Int

    ) {
    fun toAgentEntity(): AgentEntity {
        return AgentEntity(
            id = id,
            title = title,
            desc = desc,
            createdAt = createdAt,
            updatedAt = updatedAt,
            avatar = "${ApiClient.BASE_API_URL+"/outside"}$avatar"+"?token="+"${AppStore.token}",
            //author = author,
            isPublic = isPublic,
            openId = openId,
            breakMode = breakMode,
            useCount = useCount,
        )
    }
}


data class Profile(
    @SerializedName("aiAccount")
    val aiAccount: Boolean,
    @SerializedName("avatar")
    val avatar: String,
    @SerializedName("banner")
    val banner: String,
    @SerializedName("bio")
    val bio: String,
    @SerializedName("chatAIId")
    val chatAIId: String,
    @SerializedName("id")
    val id: Int,
    @SerializedName("nickname")
    val nickname: String,
    @SerializedName("trtcUserId")
    val trtcUserId: String? = null,
    @SerializedName("username")
    val username: String
){
    fun toProfileEntity(): ProfileEntity {
        return ProfileEntity(
            id = id,
            username = username,
            nickname = nickname,
            avatar = "${ApiClient.BASE_SERVER}$avatar",
            bio = bio,
            banner = "${ApiClient.BASE_SERVER}$banner",
            trtcUserId = trtcUserId ?: "",
            chatAIId = chatAIId,
            aiAccount = aiAccount
        )
    }
}
/**
 * 智能体服务
 */
interface AgentService {
    /**
     * 获取智能体列表
     * @param pageNumber 页码
     * @param pageSize 每页数量，默认 20
     * @param authorId 作者ID，可选参数，用于筛选特定作者的智能体
     * @return 智能体列表容器，包含分页信息和智能体列表，失败时返回 null
     */
    suspend fun getAgent(
    pageNumber: Int,
    pageSize: Int = 20,
    authorId: Int? = null
    ): ListContainer<AgentEntity>?

    /**
     * 根据标题关键字搜索智能体
     */
    suspend fun searchAgentByTitle(
        pageNumber: Int,
        pageSize: Int = 20,
        title: String
    ): ListContainer<AgentEntity>?

}


// ========== Agent 规则 - 领域实体 ==========

data class AgentRuleAgentInfo(
    val id: Int,
    val title: String,
    val avatar: String,
)

data class AgentRuleEntity(
    val id: Int,
    val rule: String,
    val creator: String,
    val creatorType: String,
    val scope: String,
    val agent: AgentRuleAgentInfo,
    val createdAt: String,
    val updatedAt: String,
)

data class AgentRuleListResult(
    val page: Int,
    val pageSize: Int,
    val total: Int,
    val list: List<AgentRuleEntity>,
)

data class AgentRuleQuotaEntity(
    val agentId: Int,
    val agentTitle: String,
    val baseMaxCount: Int,
    val purchasedCount: Int,
    val totalMaxCount: Int,
    val currentCount: Int,
    val remainingCount: Int,
    val usagePercent: Double,
)

// ========== Agent 规则 - Service 接口 ==========

/**
 * Agent 规则服务
 */
interface AgentRuleService {
    /**
     * 根据 OpenId 创建 Agent 规则
     * @param openId Agent 的 OpenId
     * @param rule 规则内容，不能为空
     * @throws ServiceException 创建失败时抛出异常（包括余额不足等情况）
     */
    suspend fun createAgentRuleByOpenId(openId: String, rule: String)
    
    /**
     * 修改 Agent 规则
     * @param id 规则ID
     * @param rule 新的规则内容，不能为空
     * @param openId Agent 的 OpenId，可选参数
     * @throws ServiceException 修改失败时抛出异常（包括余额不足等情况）
     */
    suspend fun updateAgentRule(id: Int, rule: String, openId: String? = null)
    
    /**
     * 删除 Agent 规则
     * @param id 规则ID
     * @throws ServiceException 删除失败时抛出异常
     */
    suspend fun deleteAgentRule(id: Int)
    
    /**
     * 查询 Agent 规则列表
     * @param openId Agent 的 OpenId
     * @param keyword 关键词搜索，可选参数
     * @param page 页码，默认 1
     * @param pageSize 每页数量，默认 10
     * @return 规则列表响应，包含分页信息和规则列表
     * @throws ServiceException 查询失败时抛出异常
     */
    suspend fun getAgentRuleList(
        openId: String,
        keyword: String? = null,
        page: Int = 1,
        pageSize: Int = 10
    ): AgentRuleListResult
    
    /**
     * 查询 Agent 规则配额使用情况
     * @param openId Agent 的 OpenId
     * @return 规则配额信息，包含基础配额、已购买配额、当前使用量等
     * @throws ServiceException 查询失败时抛出异常
     */
    suspend fun getAgentRuleQuota(openId: String): AgentRuleQuotaEntity
}

class AgentRuleServiceImpl : AgentRuleService {
    private val gson = Gson()

    override suspend fun createAgentRuleByOpenId(openId: String, rule: String) {
        val body = CreateAgentRuleRequestBody(
            rule = rule,
            promptId = null,
            openId = openId
        )
        val resp = ApiClient.api.createAgentRule(body)
        if (!resp.isSuccessful) {
            val errorText = resp.errorBody()?.string()
            try {
                val err = gson.fromJson(errorText, InsufficientBalanceError::class.java)
                if (err != null && err.code == 35600) {
                    throw ServiceException(err.message)
                }
            } catch (_: Exception) {
                // ignore parse error
            }
            throw ServiceException("创建 Agent 规则失败: HTTP ${resp.code()}")
        }
    }

    override suspend fun updateAgentRule(id: Int, rule: String, openId: String?) {
        val body = UpdateAgentRuleRequestBody(
            id = id,
            rule = rule,
            promptId = null,
            openId = openId
        )
        val resp = ApiClient.api.updateAgentRule(body)
        if (!resp.isSuccessful) {
            val errorText = resp.errorBody()?.string()
            try {
                val err = gson.fromJson(errorText, InsufficientBalanceError::class.java)
                if (err != null && err.code == 35600) {
                    throw ServiceException(err.message)
                }
            } catch (_: Exception) {
                // ignore parse error
            }
            throw ServiceException("更新 Agent 规则失败: HTTP ${resp.code()}")
        }
    }

    override suspend fun deleteAgentRule(id: Int) {
        val resp = ApiClient.api.deleteAgentRule(id)
        if (!resp.isSuccessful) {
            throw ServiceException("删除 Agent 规则失败: HTTP ${resp.code()}")
        }
    }

    override suspend fun getAgentRuleList(
        openId: String,
        keyword: String?,
        page: Int,
        pageSize: Int
    ): AgentRuleListResult {
        val resp = ApiClient.api.getAgentRuleList(
            promptId = openId,
            rule = keyword,
            page = page,
            pageSize = pageSize
        )
        val data = resp.body()?.data ?: throw ServiceException("获取 Agent 规则列表失败")
        return data.toEntity()
    }

    override suspend fun getAgentRuleQuota(openId: String): AgentRuleQuotaEntity {
        val resp = ApiClient.api.getAgentRuleQuota(openId)
        val data = resp.body()?.data ?: throw ServiceException("获取 Agent 规则配额失败")
        return data.toEntity()
    }

    private fun AgentRuleListResponse.toEntity(): AgentRuleListResult = AgentRuleListResult(
        page = page,
        pageSize = pageSize,
        total = total,
        list = list.map { it.toEntity() }
    )

    private fun AgentRule.toEntity(): AgentRuleEntity = AgentRuleEntity(
        id = id,
        rule = rule,
        creator = creator,
        creatorType = creatorType,
        scope = scope,
        agent = prompt.toEntity(),
        createdAt = createdAt,
        updatedAt = updatedAt,
    )

    private fun AgentRuleAgent.toEntity(): AgentRuleAgentInfo = AgentRuleAgentInfo(
        id = id,
        title = title,
        avatar = avatar,
    )

    private fun AgentRuleQuota.toEntity(): AgentRuleQuotaEntity = AgentRuleQuotaEntity(
        agentId = promptId,
        agentTitle = promptTitle,
        baseMaxCount = baseMaxCount,
        purchasedCount = purchasedCount,
        totalMaxCount = totalMaxCount,
        currentCount = currentCount,
        remainingCount = remainingCount,
        usagePercent = usagePercent,
    )
}

