package com.yingpaipay.business.service;

import cn.hutool.core.lang.Dict;
import com.yingpaipay.business.constant.AiAuditResultConst;
import com.yingpaipay.business.domain.dto.AiAuditDTO;
import com.yingpaipay.business.domain.dto.TextInPdfToMarkdownDTO;
import com.yingpaipay.common.ai.client.SiliconFlowClient;
import com.yingpaipay.common.ai.enumeration.SiliconFlowRole;
import com.yingpaipay.common.ai.enumeration.SiliconModel;
import com.yingpaipay.common.ai.pojo.SiliconFlowMessage;
import com.yingpaipay.common.ai.pojo.SiliconFlowResp;
import com.yingpaipay.setting.service.IAiSettingService;
import io.swagger.v3.core.util.Json;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.oss.core.OssClient;
import org.dromara.common.oss.factory.OssFactory;
import org.dromara.system.domain.vo.SysOssVo;
import org.dromara.system.service.ISysOssService;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;

@Component
@RequiredArgsConstructor
@Slf4j
public class AiAuditService {

    private final IAiSettingService settingService;
    private final ISysOssService ossService;
    private final ITextInService textInService;

    private final SiliconFlowClient siliconFlowClient;

    public AiAuditDTO audit(Long ossId) {
        if (!settingService.query().getEnabledFlag()) {
            return null;
        }
        return handleAudit(ossId);
    }

    public AiAuditDTO handleAudit(Long ossId) {
        SysOssVo ossVo = ossService.getById(ossId);

        Path tempFile;
        try {
            tempFile = Files.createTempFile("ai_audit_", ".pdf");
        } catch (IOException e) {
            log.error("创建临时文件失败", e);
            throw new RuntimeException("AI 审核临时文件创建失败", e);
        }

        try (OutputStream fos = Files.newOutputStream(tempFile)) {
            OssClient storage = OssFactory.instance(ossVo.getService());
            storage.download(ossVo.getFileName(), fos, size -> {});
        } catch (Exception e) {
            log.error("OSS 文件下载失败: ossId={}, fileName={}", ossId, ossVo.getFileName(), e);
            throw new RuntimeException("AI 审核文件下载失败", e);
        }

        // TODO 进行具体的审核环节
        AiAuditDTO dto = new AiAuditDTO();
        TextInPdfToMarkdownDTO textInDto;

        try {
            textInDto = textInService.pdfToMarkdown(Base64.getEncoder().encodeToString(Files.readAllBytes(tempFile)));
        } catch (IOException e) {
            throw new RuntimeException("解析文件失败");
        } finally {
            try {
                Files.deleteIfExists(tempFile);
            } catch (IOException e) {
                log.warn("清理临时文件失败: {}", tempFile, e);
            }
        }

        String systemContent = """
                                你是一名医药科技文件审核员，你需要负责用户传过来的文件，审核内容如下：
                                1.有页码标识的文件，页码不完整
                                2.GCP证书日期是2020年7月1日之前的
                                3.设备校准证书有效期到期日期在中心启动日期之前（中心SIV日期，可检索SIVR日期

                                最终需要给出的结果为JSON字符串，如下：
                                通过的结果：{"result":true,"rejectReason":null}
                                驳回的结果：{"result":false,"rejectReason":"驳回原因"}

                                不要返回分析过程并且在一个rejectReason中说明所有原因，我只要最终的JSON结果。
                                例如只回复：
                                {"result":true,"rejectReason":null}
                                或者只回复：
                                {"result":false,"rejectReason":"1、驳回原因1;2、驳回原因2"}
                                """;
        SiliconFlowResp resp = siliconFlowClient.askMessages(
            SiliconModel.GLM_4_7,
            new SiliconFlowMessage(SiliconFlowRole.SYSTEM, systemContent),
            new SiliconFlowMessage(SiliconFlowRole.USER, JsonUtils.toJsonString(textInDto))
        );
        log.info("回复内容 : \n{}", resp.getChoices().get(0).getMessage().getContent());
        return JsonUtils.parseObject(resp.getChoices().get(0).getMessage().getContent(), AiAuditDTO.class);
    }

}
