package cn.com.poc.message.service.impl;

import cn.com.gsst.dify_client.DifyChatClient;
import cn.com.gsst.dify_client.DifyClientFactory;
import cn.com.gsst.dify_client.enums.ResponseMode;
import cn.com.gsst.dify_client.model.chat.ChatMessage;
import cn.com.gsst.dify_client.model.chat.ChatMessageResponse;
import cn.com.poc.ai_data_audit.entity.BizAiDataAuditFileEntity;
import cn.com.poc.ai_data_audit.query.AiDataAuditRuleQueryCondition;
import cn.com.poc.ai_data_audit.query.AiDataAuditRuleQueryItem;
import cn.com.poc.ai_data_audit.service.BizAiDataAuditFileService;
import cn.com.poc.ai_data_audit.service.BizAiDataAuditRuleService;
import cn.com.poc.common.utils.DocumentLoad;
import cn.com.poc.common.utils.StringUtils;
import cn.com.poc.equity.service.BizPointDeductionRulesService;
import cn.com.poc.message.entity.AirportPDFPaperMessage;
import cn.com.poc.message.service.AirportConsumerService;
import cn.com.poc.message.topic.AirportTopic;
import cn.com.poc.ocr.entity.BizFileOcrCacheEntity;
import cn.com.poc.ocr.service.BizFileOcrCacheService;
import cn.com.yict.framemax.core.exception.BusinessException;
import cn.com.yict.framemax.tumbleweed.client.annotation.Consumer;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author alex.yao
 * @date 2025/10/30
 */
@Service
public class AirportConsumerServiceImpl implements AirportConsumerService {

    private String DIFY_BASE_URL = "https://dify.gsstcloud.com/v1";

    private ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20, 10L,
            TimeUnit.SECONDS,
            new java.util.concurrent.ArrayBlockingQueue<>(5),
            new ThreadFactoryBuilder().setNameFormat("pdf-paper-%d").build(),
            new ThreadPoolExecutor.DiscardOldestPolicy());

    @Resource
    private BizFileOcrCacheService bizFileOcrCacheService;

    @Resource
    private BizAiDataAuditFileService bizAiDataAuditFileService;

    @Resource
    private BizAiDataAuditRuleService bizAiDataAuditRuleService;

    @Override
    @Consumer(topic = AirportTopic.AIRPORT_PDF_PAPER_TOPIC)
    public void pdfPaper(AirportPDFPaperMessage message) throws Exception {
        List<String> results = new CopyOnWriteArrayList<>();

        List<Integer> ruleIdList = message.getRuleIdList();
        AiDataAuditRuleQueryCondition aiDataAuditRuleQueryCondition = new AiDataAuditRuleQueryCondition();
        aiDataAuditRuleQueryCondition.setIds(ruleIdList.toArray(new Long[ruleIdList.size()]));
        List<AiDataAuditRuleQueryItem> aiDataAuditRuleQueryItems = bizAiDataAuditRuleService.aiDataAuditRuleQueryItemList(aiDataAuditRuleQueryCondition, null);


        CountDownLatch countDownLatch = new CountDownLatch(aiDataAuditRuleQueryItems.size());
        try {
            //
            for (AiDataAuditRuleQueryItem aiDataAuditRuleQueryItem : aiDataAuditRuleQueryItems) {
                String ruleType = aiDataAuditRuleQueryItem.getDataAuditRuleType();
                if (ruleType.equals("c2c")) {
                    c2c(aiDataAuditRuleQueryItem, results, countDownLatch);
                } else if (ruleType.equals("c2f")) {
                    c2f(aiDataAuditRuleQueryItem, results, countDownLatch);
                } else if (ruleType.equals("f2f")) {
                    f2f(aiDataAuditRuleQueryItem, results, countDownLatch);
                } else {
                    countDownLatch.countDown();
                }
            }
            countDownLatch.await();
        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
    }

    // 字段对字段
    private void c2c(AiDataAuditRuleQueryItem aiDataAuditRuleQueryItem, List<String> results, CountDownLatch countDownLatch) {
        executor.submit(() -> {
            try {
                String ruleDesc = aiDataAuditRuleQueryItem.getRuleDesc();// 规则描述
                Integer firstFile = aiDataAuditRuleQueryItem.getFirstFile();// 文件1
                String firstField = aiDataAuditRuleQueryItem.getFirstField();// 字段1
                Integer secondFile = aiDataAuditRuleQueryItem.getSecondFile();// 文件2
                String secondField = aiDataAuditRuleQueryItem.getSecondField();// 字段2

                String firstFileContent = StringUtils.EMPTY;
                String secondFileContent = StringUtils.EMPTY;

                // 找到文件 并下载对应的md 或 json 文件
                BizAiDataAuditFileEntity firstAuditFileEntity = bizAiDataAuditFileService.get(firstFile);
                BizFileOcrCacheEntity bizFileOcrCacheEntity = new BizFileOcrCacheEntity();
                bizFileOcrCacheEntity.setMd5(firstAuditFileEntity.getMd5());
                List<BizFileOcrCacheEntity> firstocrCacheEntities = bizFileOcrCacheService.findByExample(bizFileOcrCacheEntity, null);
                BizFileOcrCacheEntity firstFileOcrCacheEntity = firstocrCacheEntities.get(0);
                String firstMdFileUrl = firstFileOcrCacheEntity.getMdFileUrl();
                String firstJsonFileUrl = firstFileOcrCacheEntity.getJsonFileUrl();
                if (StringUtils.isNotBlank(firstJsonFileUrl)) {
                    File file = DocumentLoad.downloadURLDocument(StringUtils.isBlank(firstJsonFileUrl) ? firstMdFileUrl : firstJsonFileUrl);
                    firstFileContent = DocumentLoad.documentToText(file);
                }

                BizAiDataAuditFileEntity secondAuditFileEntity = bizAiDataAuditFileService.get(secondFile);
                bizFileOcrCacheEntity = new BizFileOcrCacheEntity();
                bizFileOcrCacheEntity.setMd5(secondAuditFileEntity.getMd5());
                List<BizFileOcrCacheEntity> secondOcrCacheEntities = bizFileOcrCacheService.findByExample(bizFileOcrCacheEntity, null);
                BizFileOcrCacheEntity secondFileOcrCacheEntity = secondOcrCacheEntities.get(0);

                String secondMdFileUrl = firstFileOcrCacheEntity.getMdFileUrl();
                String secondJsonFileUrl = firstFileOcrCacheEntity.getJsonFileUrl();
                if (StringUtils.isNotBlank(secondJsonFileUrl)) {
                    File file = DocumentLoad.downloadURLDocument(StringUtils.isBlank(secondJsonFileUrl) ? secondMdFileUrl : secondJsonFileUrl);
                    secondFileContent = DocumentLoad.documentToText(file);
                }
                // 执行工作流
                Map<String, Object> inputs = new LinkedHashMap<>();
                inputs.put("rule", ruleDesc);
                inputs.put("doc1", firstFileContent);
                inputs.put("doc2", secondFileContent);
                inputs.put("filed_1", firstField);
                inputs.put("filed_2", secondField);
                // 创建聊天客户端
                DifyChatClient chatClient = DifyClientFactory.createChatClient(DIFY_BASE_URL, "app-1MRun3ecfLOzFS96xcWYCOOX");
                // 创建聊天消息
                ChatMessage message = ChatMessage.builder()
                        .query("run")
                        .user("0")
                        .inputs(inputs)
                        .conversationId(StringUtils.EMPTY)
                        .responseMode(ResponseMode.BLOCKING)
                        .build();

                // 发送消息并获取响应
                ChatMessageResponse response = chatClient.sendChatMessage(message);

                String result = response.getAnswer();

                results.add(result);
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                countDownLatch.countDown();
            }
        });
    }

    // 字段对文件
    private void c2f(AiDataAuditRuleQueryItem aiDataAuditRuleQueryItem, List<String> results, CountDownLatch countDownLatch) {

        countDownLatch.countDown();
    }


    // 文件对文件
    private void f2f(AiDataAuditRuleQueryItem aiDataAuditRuleQueryItem, List<String> results, CountDownLatch countDownLatch) {

        countDownLatch.countDown();
    }

}

