package cn.com.poc.ai_software_copyright.scheduler;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
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.domain.BaseInfo;
import cn.com.poc.ai_software_copyright.domain.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.FileUtils;
import cn.com.poc.common.utils.JsonUtils;
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.aggregate.MD2WordService;
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.com.poc.thirdparty.resource.demand.ai.entity.md2word.Md2WordResponse;
import cn.com.poc.thirdparty.resource.demand.ai.entity.md2word.Md2WordResult;
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 com.dexcoder.commons.utils.UUIDUtils;
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)) {
            for (BizSoftwareCopyrightEntity softwareCopyrightEntity : bizSoftwareCopyrightEntities) {
                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) {
                            String url = createSourceCodeDocument(jsonArray, "源代码");
                            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) {
                            String url = createSimpleDocument(result, "电脑使用说明书");
                            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) {
                            String url = createSimpleDocument(result, "手机使用说明书");
                            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);
                    legalFileResponse.setFileName("信息采集表");
                    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();
        for (java.lang.reflect.Field field : baseInfoFields) {
            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;
            }
        }

        java.lang.reflect.Field[] technicalContentFields = technicalContent.getClass().getDeclaredFields();
        for (java.lang.reflect.Field field : technicalContentFields) {
            field.setAccessible(true);
            try {
                Object value = field.get(technicalContent);
                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;
            }
        }
    }

    @Resource
    private MD2WordService md2WordService;

    private String createSourceCodeDocument(JSONArray jsonArray, String fileName) throws Exception {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < jsonArray.size(); i++) {
            String content = jsonArray.getString(i);
            stringBuilder.append(content);
        }
        return createSimpleDocument(stringBuilder.toString(), fileName);
    }

    private String createSimpleDocument(String content, String fileName) throws Exception {
        return md2wordAndUploadURL(content, fileName);
    }

    private String md2wordAndUploadURL(String mdContent, String fileName) throws Exception {
        File file = null;
        FileOutputStream fileOutputStream = null;
        FileInputStream fileInputStream = null;
        try {
            file = File.createTempFile(UUIDUtils.getUUID8(), ".md");
            fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(mdContent.getBytes());
            fileOutputStream.flush();

            fileInputStream = new FileInputStream(file);
            byte[] bytes = new byte[fileInputStream.available()];
            fileInputStream.read(bytes);

            String mdURL = uploadDocument(bytes, fileName);
            Md2WordResponse response = new Md2WordResponse();
            response.setFileName(fileName);
            response.setFilePath(mdURL);

            Md2WordResult md2WordResult = md2WordService.md2Word(response);
            return md2WordResult.getFilePath();
        } finally {
            if (file != null || file.exists()) {
                file.delete();
            }
            fileInputStream.close();
            fileOutputStream.close();
        }
    }


    private String uploadDocument(byte[] documentBytes, String fileName) throws Exception {
        File tempFile = null;
        try {
            tempFile = File.createTempFile(UUIDUtils.getUUID8(), 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();
            }
        }
    }
}