package com.cy.guoyan.admin.module.ai.service.aiservice;

import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSONObject;
import com.cy.guoyan.admin.framework.common.util.object.BeanUtils;
import com.cy.guoyan.admin.module.ai.controller.admin.chatdocument.vo.ChatDocumentSaveReqVO;
import com.cy.guoyan.admin.module.ai.controller.admin.chatknowledgedataset.vo.ChatKnowledgeDatasetSaveReqVO;
import com.cy.guoyan.admin.module.ai.controller.admin.chatmessage.vo.ChatMessageRespVO;
import com.cy.guoyan.admin.module.ai.controller.admin.chatmessage.vo.ChatMessageSendReqVO;
import com.cy.guoyan.admin.module.ai.dal.dataobject.chatdocument.ChatDocumentDO;
import com.cy.guoyan.admin.module.ai.dal.dataobject.chatknowledgedataset.ChatKnowledgeDatasetDO;
import com.cy.guoyan.admin.module.ai.dal.mysql.chatdocument.ChatDocumentMapper;
import com.cy.guoyan.admin.module.ai.dal.mysql.chatknowledgedataset.ChatKnowledgeDatasetMapper;
import com.cy.guoyan.admin.module.infra.api.file.FileApi;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Map;

import static com.cy.guoyan.admin.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cy.guoyan.admin.module.system.enums.ErrorCodeConstants.*;

@Service
@Slf4j
public class AiSelectionService implements AiService {

    private final AiService difyService;

    private final AiService ragflowService;

    @Resource
    private ChatKnowledgeDatasetMapper chatKnowledgeDatasetMapper;

    @Resource
    private ChatDocumentMapper chatDocumentMapper;

    @Resource
    private FileApi fileApi;

    public AiSelectionService(
            @Qualifier("dify") AiService difyService,
            @Qualifier("ragflow") AiService ragflowService) {
        this.difyService = difyService;
        this.ragflowService = ragflowService;
    }


    @Override
    @Transactional
    public JSONObject createDataset(ChatKnowledgeDatasetSaveReqVO req) throws IOException {
            JSONObject difyJson = difyService.createDataset(req);

            String difyDatasetId = difyJson.getString("id");

            String difyEmbeddingModel  = difyJson.getString("embedding_model");

            JSONObject ragflowJson = ragflowService.createDataset(req);

            JSONObject data = ragflowJson.getJSONObject("data");
            if (data == null) {
                throw new IOException("返回结果中没有 data 字段：" + ragflowJson);
            }

            String ragflowDatasetId  = data.getString("id");
            String ragflowEmbeddingModel  = data.getString("embedding_model");

            ChatKnowledgeDatasetDO aDo = new ChatKnowledgeDatasetDO();
            aDo.setName(req.getName());
            aDo.setDescription(req.getDescription());
            aDo.setDifyDatasetId(difyDatasetId);
            aDo.setRagflowDatasetId(ragflowDatasetId);
            aDo.setDifyEmbeddingModel(difyEmbeddingModel);
            aDo.setRagflowEmbeddingModel(ragflowEmbeddingModel);
            aDo.setDifyMetadataJson(difyJson.toJSONString());
            aDo.setRagflowMetadataJson(data.toJSONString());
            chatKnowledgeDatasetMapper.insert(aDo);
            return difyJson;
    }

    @Override
    @Transactional
    public void updateDataset(ChatKnowledgeDatasetSaveReqVO req) throws IOException {
            difyService.updateDataset(req);
            ragflowService.updateDataset(req);
    }

    @Override
    @Transactional
    public String deleteDataset(String id) throws IOException {
            ChatKnowledgeDatasetDO datasetDO = chatKnowledgeDatasetMapper.selectById(id);
            if (datasetDO == null) {
                throw exception(CHAT_KNOWLEDGE_DATASET_NOT_EXISTS);
            }

            String difyResult = difyService.deleteDataset(datasetDO.getDifyDatasetId());
            log.info("删除dify知识库：{}", difyResult);

            String ragflowResult = ragflowService.deleteDataset(datasetDO.getRagflowDatasetId());

            log.info("删除ragflow知识库t：{}", ragflowResult);

            chatKnowledgeDatasetMapper.deleteById(id);


        return "success";
    }



    @Override
    public JSONObject createDocumentByFile(MultipartFile file, ChatDocumentSaveReqVO createReqVO, File tmpFile) throws IOException {

        ChatKnowledgeDatasetDO dataset = chatKnowledgeDatasetMapper.selectById(createReqVO.getDatasetId());
        if (dataset == null) {
            throw exception(CHAT_KNOWLEDGE_DATASET_NOT_EXISTS);
        }

        JSONObject difyResp = null;
        JSONObject ragflowResp = null;
        String originalFilename = file.getOriginalFilename();
        createReqVO.setName(originalFilename);

        ChatDocumentDO doc = BeanUtils.toBean(createReqVO, ChatDocumentDO.class);
        doc.setDataSourceType("file_upload");
        doc.setDatasetId(createReqVO.getDatasetId());
        doc.setProcessRuleMode(createReqVO.getProcessRuleMode());


        Map<String, Object> apiFile = fileApi.getFile(originalFilename, IoUtil.readBytes(file.getInputStream()), null,null);
        log.info("DEBUG - File Upload Response: {}", apiFile);
        String fileUrl = apiFile.get("path").toString();
        doc.setFilePath(fileUrl);
        File tmp = File.createTempFile("tem_up", "_" + file.getOriginalFilename());
        file.transferTo(tmp);
        tmp.deleteOnExit();

        difyResp = difyService.createDocumentByFile(null, createReqVO.setDatasetId(dataset.getDifyDatasetId()), tmp);
        log.info("DEBUG - difyResp: {}", difyResp);

        ragflowResp = ragflowService.createDocumentByFile(null, createReqVO.setDatasetId(dataset.getRagflowDatasetId()), tmp);
        log.info("DEBUG - ragflowResp: {}", ragflowResp);

        JSONObject difyJson = difyResp.getJSONObject("document");
        JSONObject ragflowJson = ragflowResp.getJSONArray("data").getJSONObject(0);
        doc.setDifyDocumentId(difyJson.getString("id"));
        doc.setRagflowDocumentId(ragflowJson.getString("id"));
        doc.setWordCount(difyJson.getIntValue("word_count"));
        doc.setIndexingStatus(difyJson.getString("indexing_status"));
        doc.setBatch(difyResp.getString("batch"));
        doc.setFileSize(apiFile.get("size").toString());
        chatDocumentMapper.insert(doc);
        if (StringUtils.isNotBlank(doc.getDifyDocumentId())) {
            difyService.getDocumentIndexingStatus(dataset.getDifyDatasetId(), String.valueOf(doc.getId()));
        }
        if (StringUtils.isNotBlank(doc.getRagflowDocumentId())) {
            ragflowService.getDocumentIndexingStatus(dataset.getRagflowDatasetId(), String.valueOf(doc.getId()));
        }
        return difyResp;

    }

    @Override
    public void deleteDocument(String datasetId, String documentId) throws IOException {
        ChatDocumentDO documentDO = chatDocumentMapper.selectById(documentId);
        if (documentDO == null) {
            throw exception(CHAT_DOCUMENT_NOT_EXISTS);
        }

        ChatKnowledgeDatasetDO dataset = chatKnowledgeDatasetMapper.selectById(documentDO.getDatasetId());
        if (dataset == null) {
            throw exception(CHAT_KNOWLEDGE_DATASET_NOT_EXISTS);
        }

        difyService.deleteDocument(dataset.getDifyDatasetId(), documentDO.getDifyDocumentId());

        ragflowService.deleteDocument(dataset.getRagflowDatasetId(), documentDO.getRagflowDocumentId());

        chatDocumentMapper.deleteById(documentId);

    }


    @Override
    public JSONObject getDocumentIndexingStatus(String datasetId, String batch) throws IOException {
        ChatKnowledgeDatasetDO dataset = chatKnowledgeDatasetMapper.selectById(datasetId);
        if (dataset == null) {
            throw exception(CHAT_KNOWLEDGE_DATASET_NOT_EXISTS);
        }

        ChatDocumentDO doc = chatDocumentMapper.selectById(batch);

        JSONObject documentIndexingStatus = null;

        if (StringUtils.isNotBlank(doc.getDifyDocumentId())) {
            difyService.getDocumentIndexingStatus(dataset.getDifyDatasetId(), String.valueOf(doc.getId()));
        }
        if (StringUtils.isNotBlank(doc.getRagflowDocumentId())) {
             documentIndexingStatus = ragflowService.getDocumentIndexingStatus(dataset.getRagflowDatasetId(), String.valueOf(doc.getId()));
        }
        return documentIndexingStatus;
    }

    @Override
    public ChatMessageRespVO sendChatMessageBlock(ChatMessageSendReqVO sendReqVO) throws IOException {
        ChatMessageRespVO respVO = null;
        if (sendReqVO.getAppType() == null) {
            throw exception(CHAT_MODEL_NOT_EXISTS);
        }
        if (sendReqVO.getAppType() == 1) {
            respVO = difyService.sendChatMessageBlock(sendReqVO);
        } else if (sendReqVO.getAppType() == 2) {
            respVO = ragflowService.sendChatMessageBlock(sendReqVO);
        }
        return respVO;
    }

    public String getDocId(String docId, Integer appType) {
        String path = null;
        if (appType == null) {
            throw exception(CHAT_MODEL_NOT_EXISTS);
        }
        if (appType == 1) {
            path = difyService.getDocId(docId,appType);
        } else if (appType == 2) {
            path = ragflowService.getDocId(docId,appType);
        }
        return path;
    }
}

