package org.jeecg.modules.airag.api;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.airag.api.IAiragBaseApi;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootBizTipException;
import org.jeecg.common.util.AssertUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.airag.app.entity.AiragApp;
import org.jeecg.modules.airag.app.service.IAiragAppService;
import org.jeecg.modules.airag.app.service.IAiragVariableService;
import org.jeecg.modules.airag.llm.consts.LLMConsts;
import org.jeecg.modules.airag.llm.entity.AiragKnowledgeDoc;
import org.jeecg.modules.airag.llm.service.IAiragKnowledgeDocService;
import org.jeecg.modules.airag.prompts.entity.AiragPrompts;
import org.jeecg.modules.airag.prompts.service.IAiragPromptsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

/**
 * airag baseAPI 实现类
 */
@Slf4j
@Primary
@Service("airagBaseApiImpl")
public class AiragBaseApiImpl implements IAiragBaseApi {

    @Autowired
    private IAiragKnowledgeDocService airagKnowledgeDocService;

    @Override
    public String knowledgeWriteTextDocument(String knowledgeId, String title, String content, String segmentConfig) {
        AssertUtils.assertNotEmpty("知识库ID不能为空", knowledgeId);
        AssertUtils.assertNotEmpty("写入内容不能为空", content);
        AiragKnowledgeDoc knowledgeDoc = new AiragKnowledgeDoc();
        knowledgeDoc.setKnowledgeId(knowledgeId);
        knowledgeDoc.setTitle(title);
        knowledgeDoc.setType(LLMConsts.KNOWLEDGE_DOC_TYPE_TEXT);
        knowledgeDoc.setContent(content);
        // 将分段策略配置写入文档的metadata中，EmbeddingHandler会从中读取分段配置
        if (oConvertUtils.isNotEmpty(segmentConfig)) {
            knowledgeDoc.setMetadata(segmentConfig);
        }
        Result<?> result = airagKnowledgeDocService.editDocument(knowledgeDoc);
        if (!result.isSuccess()) {
            throw new JeecgBootBizTipException(result.getMessage());
        }
        if (knowledgeDoc.getId() == null) {
            throw new JeecgBootBizTipException("知识库文档ID为空");
        }
        log.info("[AI-KNOWLEDGE] 文档写入完成，知识库:{}, 文档ID:{}", knowledgeId, knowledgeDoc.getId());
        return knowledgeDoc.getId();
    }

    @Autowired
    private IAiragAppService airagAppService;

    @Autowired
    private IAiragVariableService airagVariableService;

    @Autowired
    private IAiragPromptsService airagPromptsService;

    @Override
    public String getChatVariable(String appId, String username, String name) {
        return airagVariableService.getVariable(username, appId, name);
    }

    @Override
    public void setChatVariable(String appId, String username, String name, String value) {
        AssertUtils.assertNotEmpty("应用ID不能为空", appId);
        AssertUtils.assertNotEmpty("用户名不能为空", username);
        AssertUtils.assertNotEmpty("变量名不能为空", name);
        airagVariableService.updateVariable(username, appId, name, value != null ? value : "");
    }

    @Override
    public String getMemoryIdByAppId(String appId) {
        if (oConvertUtils.isEmpty(appId)) {
            return null;
        }
        LambdaQueryWrapper<AiragApp> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AiragApp::getId, appId)
                .eq(AiragApp::getIzOpenMemory, 1)
                .isNotNull(AiragApp::getMemoryId)
                .ne(AiragApp::getMemoryId, "")
                .select(AiragApp::getMemoryId);
        AiragApp app = airagAppService.getOne(queryWrapper);
        return app != null ? app.getMemoryId() : null;
    }

    @Override
    public String getPromptContent(String promptId) {
        if (oConvertUtils.isEmpty(promptId)) {
            return null;
        }
        AiragPrompts prompt = airagPromptsService.getById(promptId);
        if (prompt == null) {
            log.warn("[AiragBaseApi]提示词不存在，promptId={}", promptId);
            return null;
        }
        return prompt.getContent();
    }

}
