package cn.com.poc.ai_software_copyright.scheduler;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

import static cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightRedisKey.CALL_BACK;

import cn.com.poc.ai_software_copyright.agent.SoftwareCopyRightAgent;
import cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightEnum;
import cn.com.poc.ai_software_copyright.convert.BizSoftwareCopyrightConvert;
import cn.com.poc.ai_software_copyright.convert.BizSoftwareCopyrightDocRecordConvert;
import cn.com.poc.ai_software_copyright.domian.BaseInfo;
import cn.com.poc.ai_software_copyright.domian.TechnicalContent;
import cn.com.poc.ai_software_copyright.dto.SoftwareCopyRightDto;
import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightDocRecordEntity;
import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightEntity;
import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightDocRecordService;
import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightService;
import cn.com.poc.common.constant.CommonConstant;
import cn.com.poc.common.service.BosConfigService;
import cn.com.poc.common.service.RedisService;
import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.common.utils.ListUtils;
import cn.com.poc.common.utils.StringUtils;
import cn.com.poc.message.entity.SoftwareCopyRightMessage;
import cn.com.poc.message.service.SoftwareCopyRightProduceService;
import cn.com.poc.thirdparty.resource.demand.ai.aggregate.LegalService;
import cn.com.poc.thirdparty.resource.demand.ai.entity.legal.Item;
import cn.com.poc.thirdparty.resource.demand.ai.entity.legal.LegalFileResponse;
import cn.com.poc.thirdparty.resource.demand.ai.entity.legal.LegalFileResult;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * @author alex.yao
 * @date 2025/12/26
 */
@Component
public class SoftwareCopyRightScheduler {

    private static final String DOCX_EXTENSION = ".docx";

    private static final String DOCX_FILE_TYPE = "docx";

    private static final String INFORMATION_TEMPLATE_FILE_URL =
            "https://gsst-poe-sit.gz.bcebos.com/v1/software-copyright/%E6%A8%A1%E6%9D%BF.docx";

    @Resource
    private RedisService redisService;

    @Resource
    private BosConfigService bosConfigService;

    @Resource
    private LegalService legalService;

    @Resource
    private SoftwareCopyRightAgent softwareCopyRightAgent;

    @Resource
    private SoftwareCopyRightProduceService produceService;

    @Resource
    private BizSoftwareCopyrightService bizSoftwareCopyrightService;

    @Resource
    private BizSoftwareCopyrightDocRecordService bizSoftwareCopyrightDocRecordService;


    @Scheduled(fixedDelay = 1000 * 30)
    public void checkDeftSoftwareCopyRightTask() {
        BizSoftwareCopyrightEntity bizSoftwareCopyrightEntity = new BizSoftwareCopyrightEntity();
        bizSoftwareCopyrightEntity.setGeneratedStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Daft.name());
        bizSoftwareCopyrightEntity.setIsDeleted(CommonConstant.IsDeleted.N);
        List<BizSoftwareCopyrightEntity> bizSoftwareCopyrightEntities =
                bizSoftwareCopyrightService.findByExample(bizSoftwareCopyrightEntity, null);

        if (CollectionUtils.isNotEmpty(bizSoftwareCopyrightEntities)) {
            for (BizSoftwareCopyrightEntity softwareCopyrightEntity : bizSoftwareCopyrightEntities) {
                String redisKey = CALL_BACK + softwareCopyrightEntity.getId();

                if (redisService.hasKey(redisKey)) {
                    Object res = redisService.get(redisKey);
                    if (ObjectUtil.isEmpty(res)) {
                        continue;
                    }
                    String resStr = res.toString();
                    if (resStr.equals("error")) { // 失败
                        SoftwareCopyRightMessage message = new SoftwareCopyRightMessage();
                        message.setStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Error);
                        produceService.updateStatus(message);
                    } else if (resStr.equals("success")) {
                        SoftwareCopyRightMessage message = new SoftwareCopyRightMessage();
                        message.setId(softwareCopyrightEntity.getId());
                        message.setStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Pending);
                        message.setBaseInfo(softwareCopyrightEntity.getBaseInfo());
                        message.setTechnicalContent(softwareCopyrightEntity.getTechnicalContent());
                        message.setReferenceDocumentFileUrl(softwareCopyrightEntity.getReferenceDocumentFileUrl());
                        message.setGeneratedDocType(softwareCopyrightEntity.getGeneratedDocType());
                        produceService.submitTask(message);
                    }
                } else {
                    // 设置Redis键值，避免重复处理
                    redisService.set(redisKey, null);
                    SoftwareCopyRightDto softwareCopyRightDto =
                            BizSoftwareCopyrightConvert.entityToDto(softwareCopyrightEntity);
                    List<String> files = softwareCopyRightDto.getReferenceDocumentFileUrl();
                    BaseInfo baseInfo = softwareCopyRightDto.getBaseInfo();
                    TechnicalContent technicalContent = softwareCopyRightDto.getTechnicalContent();
                    softwareCopyRightAgent.generatedBaseDoc(redisKey, files, baseInfo, technicalContent);
                }
            }
        }
    }


    @Scheduled(fixedDelay = 1000 * 15)
    public void checkRunningSoftwareCopyRightTask() {
        BizSoftwareCopyrightEntity bizSoftwareCopyrightEntity = new BizSoftwareCopyrightEntity();
        bizSoftwareCopyrightEntity.setGeneratedStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Running.name());
        bizSoftwareCopyrightEntity.setIsDeleted(CommonConstant.IsDeleted.N);
        List<BizSoftwareCopyrightEntity> bizSoftwareCopyrightEntities =
                bizSoftwareCopyrightService.findByExample(bizSoftwareCopyrightEntity, null);

        if (CollectionUtils.isNotEmpty(bizSoftwareCopyrightEntities)) {
            bizSoftwareCopyrightEntities.parallelStream().forEach(softwareCopyrightEntity -> {
                after(softwareCopyrightEntity);
            });
        }
    }

    private void after(BizSoftwareCopyrightEntity softwareCopyrightEntity) {

        List<String> docTypes;
        try {
            if (StringUtils.isBlank(softwareCopyrightEntity.getGeneratedDocType())) {
                return;
            }
            docTypes = JsonUtils.deSerialize(softwareCopyrightEntity.getGeneratedDocType(), new TypeReference<List<String>>() {
            }.getType());
            if (CollectionUtils.isEmpty(docTypes)) {
                return;
            }
        } catch (Exception e) {
            throw new IllegalArgumentException("Invalid generatedDocType format", e);
        }

        String redisKey = CALL_BACK + softwareCopyrightEntity.getId();
        boolean allDone = true;
        boolean isChange = false;
        BizSoftwareCopyrightDocRecordEntity recordEntity =
                bizSoftwareCopyrightDocRecordService.getByRelationId(softwareCopyrightEntity.getId());
        if (recordEntity == null) {
            recordEntity = new BizSoftwareCopyrightDocRecordEntity();
            recordEntity.setRelationId(softwareCopyrightEntity.getId());
        }


        for (String docType : docTypes) {
            AiSoftWareCopyRightEnum.DOC_TYPE type;
            try {
                type = AiSoftWareCopyRightEnum.DOC_TYPE.valueOf(docType);
            } catch (IllegalArgumentException e) {
                // 跳过无效的枚举值
                continue;
            }

            if (type.equals(AiSoftWareCopyRightEnum.DOC_TYPE.source_code)) {
                String sourceCode = recordEntity.getSourceCode();
                if (StringUtils.isBlank(sourceCode)) {
                    Object obj = redisService.get(redisKey + ":" + type.name());
                    if (ObjectUtil.isEmpty(obj)) {
                        allDone = false;
                        continue;
                    }
                    try {
                        JSONObject jsonObject = JSONObject.parseObject(obj.toString());
                        JSONArray jsonArray = jsonObject.getJSONArray("result");
                        if (jsonArray != null) {
                            byte[] documentBytes = createSourceCodeDocument(jsonArray);
                            String url =
                                    uploadDocument(documentBytes, "source_code_" + softwareCopyrightEntity.getId());
                            recordEntity.setSourceCode(url);
                            isChange = true;
                        }
                    } catch (Exception e) {
                        // 记录错误但继续处理其他类型
                        continue;
                    }
                }
            } else if (type.equals(AiSoftWareCopyRightEnum.DOC_TYPE.pc_operating_manual)) {
                String pcOperatingManual = recordEntity.getPcOperatingManual();
                if (StringUtils.isBlank(pcOperatingManual)) {
                    Object obj = redisService.get(redisKey + ":" + type.name());
                    if (ObjectUtil.isEmpty(obj)) {
                        allDone = false;
                        continue;
                    }
                    try {
                        JSONObject jsonObject = JSONObject.parseObject(obj.toString());
                        String result = jsonObject.getString("result");
                        if (result != null) {
                            byte[] documentBytes = createSimpleDocument(result);
                            String url = uploadDocument(documentBytes,
                                    AiSoftWareCopyRightEnum.DOC_TYPE.pc_operating_manual.name() + "_" +
                                            softwareCopyrightEntity.getId());
                            recordEntity.setPcOperatingManual(url);
                            isChange = true;
                        }
                    } catch (Exception e) {
                        // 记录错误但继续处理其他类型
                        continue;
                    }
                }
            } else if (type.equals(AiSoftWareCopyRightEnum.DOC_TYPE.ph_operating_manual)) {
                String phOperatingManual = recordEntity.getPhOperatingManual();
                if (StringUtils.isBlank(phOperatingManual)) { // 修复：使用正确的变量名
                    Object obj = redisService.get(redisKey + ":" + type.name());
                    if (ObjectUtil.isEmpty(obj)) {
                        allDone = false;
                        continue;
                    }
                    try {
                        JSONObject jsonObject = JSONObject.parseObject(obj.toString());
                        String result = jsonObject.getString("result");

                        if (result != null) {
                            byte[] documentBytes = createSimpleDocument(result);
                            String url = uploadDocument(documentBytes,
                                    AiSoftWareCopyRightEnum.DOC_TYPE.ph_operating_manual.name() + "_" +
                                            softwareCopyrightEntity.getId());
                            recordEntity.setPhOperatingManual(url);
                            isChange = true;
                        }
                    } catch (Exception e) {
                        // 记录错误但继续处理其他类型
                        continue;
                    }
                }
            } else if (type.equals(AiSoftWareCopyRightEnum.DOC_TYPE.information)) {
                if (StringUtils.isBlank(recordEntity.getInformation())) {
                    SoftwareCopyRightDto softwareCopyRightDto =
                            BizSoftwareCopyrightConvert.entityToDto(softwareCopyrightEntity);
                    BaseInfo baseInfo = softwareCopyRightDto.getBaseInfo();
                    TechnicalContent technicalContent = softwareCopyRightDto.getTechnicalContent();
                    List<Item> items = new ArrayList<>();
                    buildItem(baseInfo, items, technicalContent);
                    LegalFileResponse legalFileResponse = new LegalFileResponse();
                    legalFileResponse.setItems(items);
                    legalFileResponse.setFilePath(INFORMATION_TEMPLATE_FILE_URL);
                    LegalFileResult legalFileResult = legalService.legalFile(legalFileResponse);
                    recordEntity.setInformation(legalFileResult.getFilePath());
                    isChange = true;
                }
            }
        }
        if (isChange) {
            recordEntity = recordEntity.getId() != null ?
                    bizSoftwareCopyrightDocRecordService.update(recordEntity) :
                    bizSoftwareCopyrightDocRecordService.save(recordEntity);
        }
        //检查是否文档全部生成
        if (allDone) {
            softwareCopyrightEntity.setGeneratedStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Complete.name());
            bizSoftwareCopyrightService.update(softwareCopyrightEntity);
        }
    }

    private void buildItem(BaseInfo baseInfo, List<Item> items, TechnicalContent technicalContent) {
        // 处理baseInfo,technicalContent的所有字段
        java.lang.reflect.Field[] baseInfoFields = baseInfo.getClass().getDeclaredFields();
        java.lang.reflect.Field[] technicalContentFields = technicalContent.getClass().getDeclaredFields();
        java.lang.reflect.Field[] fileds =
                new java.lang.reflect.Field[baseInfoFields.length + technicalContentFields.length];

        System.arraycopy(baseInfoFields, 0, fileds, 0, baseInfoFields.length);
        System.arraycopy(technicalContentFields, 0, fileds, baseInfoFields.length, technicalContentFields.length);

        for (java.lang.reflect.Field field : fileds) {
            field.setAccessible(true);
            try {
                Object value = field.get(baseInfo);
                List<String> values = new ArrayList<>();
                if (value == null) {
                    values.add(StringUtils.SPACE);
                }
                if (value != null) {
                    values.add(value.toString());
                }
                Item item = new Item();
                item.setKey(field.getName());
                item.setValue(values);
                item.setType("text");
                items.add(item);
            } catch (IllegalAccessException e) {
                //todo 记录错误但继续处理其他字段
                continue;
            }
        }
    }


    private byte[] createSourceCodeDocument(JSONArray jsonArray) throws Exception {
        org.apache.poi.xwpf.usermodel.XWPFDocument document =
                new org.apache.poi.xwpf.usermodel.XWPFDocument();
        try {
            for (int i = 0; i < jsonArray.size(); i++) {
                String content = jsonArray.getString(i);
                org.apache.poi.xwpf.usermodel.XWPFParagraph contentParagraph = document.createParagraph();
                org.apache.poi.xwpf.usermodel.XWPFRun contentRun = contentParagraph.createRun();
                String[] split = content.split("\n");
                for (String line : split) {
                    contentRun.setText(line);
                    contentRun.addBreak();
                }
            }

            java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
            document.write(out);
            return out.toByteArray();
        } finally {
            document.close();
        }
    }

    private byte[] createSimpleDocument(String content) throws Exception {
        org.apache.poi.xwpf.usermodel.XWPFDocument document =
                new org.apache.poi.xwpf.usermodel.XWPFDocument();

        try {
            org.apache.poi.xwpf.usermodel.XWPFParagraph contentParagraph = document.createParagraph();
            org.apache.poi.xwpf.usermodel.XWPFRun contentRun = contentParagraph.createRun();
            String[] split = content.split("\n");
            for (String line : split) {
                contentRun.setText(line);
                contentRun.addBreak();
            }

            java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
            document.write(out);
            return out.toByteArray();
        } finally {
            document.close();
        }
    }

    private String uploadDocument(byte[] documentBytes, String fileName) throws Exception {
        File tempFile = null;
        try {
            tempFile = File.createTempFile(fileName, DOCX_EXTENSION);
            FileUtil.writeBytes(documentBytes, tempFile);
            try (FileInputStream fileInputStream = new FileInputStream(tempFile)) {
                return bosConfigService.upload(fileInputStream, DOCX_FILE_TYPE, "");
            }
        } finally {
            if (tempFile != null && tempFile.exists()) {
                tempFile.delete();
            }
        }
    }
}