package com.lanyuanxiaoyao.digtal.market.service

import cn.hutool.json.JSONUtil
import com.lanyuanxiaoyao.digtal.market.ai.Chat
import com.lanyuanxiaoyao.digtal.market.ai.QianfanChat
import com.lanyuanxiaoyao.digtal.market.ai.ZhipuChat
import dev.failsafe.Failsafe
import dev.failsafe.RetryPolicy
import dev.failsafe.function.CheckedSupplier
import kotlin.time.Duration.Companion.seconds
import kotlin.time.toJavaDuration
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service

data class Description(
    val title: String,
    val author: String,
    val subtitle: String,
    val description: String,
    val tags: String,
)

@Service
class DescriptionService {
    private val logger = LoggerFactory.getLogger(javaClass)
    private val retryPolicy = RetryPolicy
        .builder<Any>()
        .withDelay(10.seconds.toJavaDuration())
        .withMaxRetries(2)
        .build()

    private val chats = listOf(
        ZhipuChat(),
        QianfanChat(),
    )

    fun parseDescription(content: String?): Description? {
        return content?.let {
            if (it.isNotBlank()) {
                var description: String?
                for (chat in chats) {
                    try {
                        description = Failsafe
                            .with(retryPolicy)
                            .get(CheckedSupplier {
                                chat.ask(
                                    // language=text
                                    Chat.Companion.SystemMessage("您作为专职中文新闻编辑，您需要总结归纳输入的文稿(忽略任何html标签)，强调时间、数据、人物、政策、法律等关键信息。请注意，您只能写一整段文字，不能分点或分段，也不能添加任何其他与内容无关的提示性文字。请使用以下模板输出符合JSON格式的结果(不添加任何Markdown代码格式)：{\"title\":\"(文章标题)\",\"subtitle\":\"(一句话概要)\",\"author\":\"(文章的来源、出处的机构或作者)\",\"description\":\"(400字概要)\",\"tags\":\"(精准中文关键词标签，最多10个，使用英文逗号分隔)\"}"),
                                    Chat.Companion.UserMessage(content)
                                )
                            })
                        logger.info("AI答复: {}", description)
                        if (description.isNullOrBlank()) {
                            continue
                        }
                        val root = JSONUtil.parse(
                            description
                                .replace("```json", "")
                                .replace("```", "")
                        )
                        val title = root.getByPath("title", String::class.java)
                        val author = root.getByPath("author", String::class.java)
                        val subtitle = root.getByPath("subtitle", String::class.java)
                        val desc = root.getByPath("description", String::class.java)
                        val tags = root
                            .getByPath("tags", String::class.java)
                            .replace("，", ",")
                        return@let Description(title, author, subtitle, desc, tags)
                    } catch (e: Throwable) {
                        logger.error("json解析失败", e)
                        continue
                    }
                }
                null
            } else null
        }
    }
}