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

import cn.com.poc.agent_application.entity.BizAgentApplicationGcConfigEntity;
import cn.com.poc.agent_application.service.BizAgentApplicationGcConfigService;
import cn.com.poc.ai_data_audit.dto.FileUploadDto;
import cn.com.poc.ai_data_audit.dto.FileUploadReturnDto;
import cn.com.poc.ai_data_audit.entity.AIDataAuditMatchFileNameResponse;
import cn.com.poc.ai_data_audit.service.DataAuditService;
import cn.com.poc.common.utils.DocumentLoad;
import cn.com.poc.law.entity.motorVehicleDrivingComplaint.Plaintiff;
import cn.com.poc.thirdparty.resource.demand.ai.aggregate.MinerUOcrService;
import cn.com.poc.thirdparty.resource.demand.ai.constants.LLMRoleEnum;
import cn.com.poc.thirdparty.resource.demand.ai.entity.dialogue.Message;
import cn.com.poc.thirdparty.resource.demand.ai.entity.largemodel.LargeModelDemandResult;
import cn.com.poc.thirdparty.resource.demand.ai.entity.largemodel.LargeModelResponse;
import cn.com.poc.thirdparty.resource.demand.ai.entity.orc.minerU.MinerUOcrResult;
import cn.com.poc.thirdparty.service.LLMService;
import cn.com.yict.framemax.core.exception.BusinessException;
import cn.com.yict.framemax.core.service.impl.BaseServiceImpl;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Service
public class DataAuditServiceImpl extends BaseServiceImpl
        implements DataAuditService {
    @Resource
    private LLMService llmService;

    @Resource
    private BizAgentApplicationGcConfigService bizAgentApplicationGcConfigService;

    final private ThreadPoolExecutor executor = new ThreadPoolExecutor(16, 64, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<>(100));

    @Override
    public List fileUploadAndProcessing(List<FileUploadDto> fileUploadDtoList) throws ExecutionException, InterruptedException {
        fileUploadDtoList.stream().collect(Collectors.groupingBy(item -> item.getFileName()));

        // 获取单个文件的文件名
        List<String> fileNames = fileUploadDtoList.stream()
                .map(item -> item.getFileName())
                .collect(Collectors.toList());

        CompletableFuture<List<AIDataAuditMatchFileNameResponse>> extractFileFuture = CompletableFuture.supplyAsync(() -> {
            try {
                return matchOriginalTemplateAndUploadFile(fileNames);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }, executor).exceptionally(ex -> {
            return new ArrayList<AIDataAuditMatchFileNameResponse>();
        });

        CompletableFuture<MinerUOcrResult> ocrFuture = CompletableFuture.supplyAsync(() -> {
            try {
                return ocrPrase(new File("1"));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }, executor).exceptionally(ex -> {
            return new MinerUOcrResult();
        });

        // 等待所有任务完成并获取结果
        CompletableFuture.allOf(extractFileFuture, ocrFuture).join();
        List<AIDataAuditMatchFileNameResponse> aiDataAuditMatchFileNameResponses = extractFileFuture.get();
        MinerUOcrResult minerUOcrResult = ocrFuture.get();


        Map<String, String> fileNameMap = new HashMap<>();
//        fileNameMap.put("DOC-01","Work Permit Application Details");
//        fileNameMap.put("DOC-02","Work Permit Extension Details");
        fileNameMap.put("DOC-03", "Work Method Statement");
        fileNameMap.put("DOC-04", "Safety Method Statement or Safety Plan");
        fileNameMap.put("DOC-05", "Risk Assessment");
        fileNameMap.put("DOC-06", "Work Programme");
        fileNameMap.put("DOC-07", "Location Plan");
        fileNameMap.put("DOC-08", "HKIA Contractor Safety (Construction & Maintenance) Training Record");
        fileNameMap.put("DOC-09", "HKIA BRAAS Check Form or BRAAS Exemption Declaration Form");
        fileNameMap.put("DOC-10", "Premises Endorser Declaration Form for Work Permit Application");
        fileNameMap.put("DOC-11", "OCWIP");
        fileNameMap.put("DOC-12", "Insurance");
        fileNameMap.put("DOC-13", "Pay-in-Slip for Work Permit Processing Fee");
        fileNameMap.put("DOC-14", "HKIA APM Safety Video Training and Examination Record");
        fileNameMap.put("DOC-15", "Aerodrome Safety Risk Assessment");
        fileNameMap.put("DOC-16", "System Change Request (SCR)");
        fileNameMap.put("DOC-17", "CCTV Equipment Configuration Request Form");
        fileNameMap.put("DOC-18", "Permit to Dig");
        fileNameMap.put("DOC-19", "Temporary Traffic Management Plan");

        List<AIDataAuditMatchFileNameResponse> otherList = new ArrayList<>();
        List<FileUploadReturnDto> fileUploadReturnDtoList = new ArrayList<>();

        if (fileNames.contains("Form.pdf")) {
            FileUploadReturnDto fileUploadReturnDto = new FileUploadReturnDto();
            fileUploadReturnDto.setOrginalTemplateCode("DOC-01");
            fileUploadReturnDto.setOrginalTemplateName("Work Permit Application Details");
            fileUploadReturnDto.setUploadFileName("Form.pdf");
            fileUploadReturnDtoList.add(fileUploadReturnDto);

            FileUploadReturnDto fileUploadExtensionDto = new FileUploadReturnDto();
            fileUploadExtensionDto.setOrginalTemplateCode("DOC-02");
            fileUploadExtensionDto.setOrginalTemplateName("Work Permit Extension Details");
            fileUploadExtensionDto.setUploadFileName("");
            fileUploadReturnDtoList.add(fileUploadExtensionDto);
        }


        //执行类型匹配
        for (AIDataAuditMatchFileNameResponse aiDataAuditMatchFileNameResponse : aiDataAuditMatchFileNameResponses) {
            if (StringUtils.isBlank(aiDataAuditMatchFileNameResponse.getTemplateName())) {
                otherList.add(aiDataAuditMatchFileNameResponse);
                continue;
            }
            FileUploadReturnDto fileUploadReturnDto = new FileUploadReturnDto();
            fileUploadReturnDto.setOrginalTemplateName(aiDataAuditMatchFileNameResponse.getTemplateName());
            fileUploadReturnDto.setOrginalTemplateCode(aiDataAuditMatchFileNameResponse.getTemplateCode());
            fileUploadReturnDto.setUploadFileName(aiDataAuditMatchFileNameResponse.getUploadFileName());
            fileUploadReturnDtoList.add(fileUploadReturnDto);
        }

        for (AIDataAuditMatchFileNameResponse other : otherList) {
            FileUploadReturnDto fileUploadReturnDto = new FileUploadReturnDto();
            fileUploadReturnDto.setOrginalTemplateName("ohter");
            fileUploadReturnDto.setOrginalTemplateCode("ohter");
            fileUploadReturnDto.setUploadFileName(other.getUploadFileName());
            fileUploadReturnDtoList.add(fileUploadReturnDto);
        }
        return fileUploadReturnDtoList;
    }

    public List<AIDataAuditMatchFileNameResponse> matchOriginalTemplateAndUploadFile(List<String> fileNames) throws Exception {
        // 获取对话提示词
        String promptCode = "AIDataAuditMatchFileName";
        BizAgentApplicationGcConfigEntity documentDialoguePrompt = bizAgentApplicationGcConfigService.getByConfigCode(promptCode);
        if (documentDialoguePrompt == null || StringUtils.isBlank(documentDialoguePrompt.getConfigSystem())) {
            throw new BusinessException("获取对话提示词失败");
        }

        fileNames = fileNames.stream().filter(item -> !item.contains("Form.pdf")).collect(Collectors.toList());
        String prompt = documentDialoguePrompt.getConfigSystem().replace("${uploadFileName}", JSON.toJSONString(fileNames));

        //组装请求参数
        List<Message> messages = buildMessages("", null, prompt);
        LargeModelResponse largeModelResponse = new LargeModelResponse();
        largeModelResponse.setModel("deepseek-v3");//获取模型);
        largeModelResponse.setTopP(0.1f);//获取模型);
        largeModelResponse.setTemperature(0.1f);//获取模型);
        largeModelResponse.setMessages(messages.toArray(new Message[0]));
        largeModelResponse.setStream(false);
        LargeModelDemandResult chat = llmService.chat(largeModelResponse);
        Plaintiff plaintiff = new Plaintiff();
        if (ObjectUtil.isEmpty(chat) || !chat.getCode().equals("0")) {
            throw new BusinessException("获取失败");
        }
        String message = chat.getMessage().replaceAll("```json", StringUtils.EMPTY).replaceAll("```", StringUtils.EMPTY);
        List<AIDataAuditMatchFileNameResponse> aIDataAuditMatchFileNameResponses = JSON.parseArray(message, AIDataAuditMatchFileNameResponse.class);
        if (ObjectUtil.isEmpty(plaintiff)) {
            throw new BusinessException("提取失败");
        }
        return aIDataAuditMatchFileNameResponses;
    }

    private List<Message> buildMessages(String input, String fileUrl, String prompt) throws Exception {


        // 加载文件
        String fileContent = StringUtils.EMPTY;
        if (StringUtils.isNoneBlank(fileUrl)) {
            File file = DocumentLoad.downloadURLDocument(fileUrl);
            fileContent = DocumentLoad.documentToText(file);
        }

        // 加载对话提示词
//        String prompt = documentDialoguePrompt.getConfigSystem();
//        if (CollectionUtils.isNotEmpty(knowledgeContentResults)) {
//            String knowledgeContent = JsonUtils.serialize(knowledgeContentResults);
//            prompt = prompt.replace("${knowledgeContent}", knowledgeContent);
//        } else {
//            prompt = prompt.replace("${knowledgeContent}", StringUtils.EMPTY);
//        }
//        if (toolFunction != null) {
//            prompt = prompt.replace("${toolFunction}", JsonUtils.serialize(toolFunction));
//        }
//
//        prompt = prompt.replace("${question}", input).replace("${fileContent}", fileContent);

        // 配置message
        List<Message> messages = new ArrayList<>();
        Message systemMessage = new Message();
        systemMessage.setContent(prompt);
        systemMessage.setRole(LLMRoleEnum.SYSTEM.getRole());
        messages.add(systemMessage);


        // 用户输入
        Message message = new Message();
        message.setContent("");
        message.setRole(LLMRoleEnum.USER.getRole());
        messages.add(message);
//        logger.info("--------- Build Messages dialogsId:{},messages:{}--------------", dialogsId, messages);
        return messages;
    }

    public MinerUOcrResult ocrPrase(File file) {
//        return minerUOcrService.fileParse(file);
        return new MinerUOcrResult();
    }

    public List<FileUploadDto> handleDuplicateFileNames(List<FileUploadDto> fileUploadDtoList) {
        Map<String, Integer> fileNameCountMap = new HashMap<>();

        return fileUploadDtoList.stream().map(dto -> {
            String originalFileName = dto.getFileName();
            int count = fileNameCountMap.getOrDefault(originalFileName, 0);
            fileNameCountMap.put(originalFileName, count + 1);

            if (count > 0) {
                String newFileName = originalFileName + "(" + count + ")";
                dto.setFileName(newFileName);
            }
            return dto;
        }).collect(Collectors.toList());
    }

}