package com.yaoyicloud.service.impl;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import cn.hutool.core.util.IdUtil;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectInputStream;
import com.yaoyicloud.config.CommonDataCache;
import com.yaoyicloud.config.FilerepoProperties;
import com.yaoyicloud.config.RelationCounterRedisUtil;
import com.yaoyicloud.config.ReportPathManager;
import com.yaoyicloud.constant.enums.ModuleType;
import com.yaoyicloud.easier.common.file.core.FileProperties;
import com.yaoyicloud.easier.common.file.core.FileTemplate;
import com.yaoyicloud.entity.ReportGenerationResult;
import com.yaoyicloud.render.CoverRender;
import com.yaoyicloud.render.platform.AttachmentSectionRender;
import com.yaoyicloud.render.platform.update.OtherRender;
import com.yaoyicloud.render.platform.update.BusinessRender;
import com.yaoyicloud.render.platform.update.OperationalRender;
import com.yaoyicloud.render.platform.update.JudicialRender;
import com.yaoyicloud.render.platform.update.TaxRender;
import com.yaoyicloud.service.ReportUpdateService;
import com.yaoyicloud.tools.DocxUtil;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import static com.yaoyicloud.config.SessionInterceptor.SESSION_MAP;

@Slf4j
@Service
@RequiredArgsConstructor
public class FxyReportUpdateServiceImpl implements ReportUpdateService {

    private final FilerepoProperties filerepoProperties;
    private final ReportPathManager reportPathManager;
    private final CommonDataCache commonDataCache;
    private final RelationCounterRedisUtil relationCounterRedisUtil;
    private final FileTemplate ossTemplate;
    private final FileProperties properties;

    @SuppressWarnings("checkstyle:ReturnCount")
    @Override
    public ReportGenerationResult createPlusVersionCheckReport(String data, Long relationId, ModuleType moduleType) {
        String sessionId = SESSION_MAP.get(relationId.toString());
        String reportPath = null;
        String mergedReportPath = null;
        boolean isLastModule = false;
        try {
            // oss 获取文件
            S3Object s3Object = ossTemplate.getObject(properties.getBucketName(), moduleType.getType() + ".docx");
            S3ObjectInputStream objectContent = s3Object.getObjectContent();

            Integer count = relationCounterRedisUtil.getCount(relationId);

            // 处理指定模块
            reportPath = processModule(moduleType, data, objectContent, sessionId, relationId, count);

            reportPathManager.addReportPath(sessionId, reportPath);
            relationCounterRedisUtil.increment(relationId, 1);

            isLastModule = reportPath.contains("ATTACHMENTSECTION");
            if (isLastModule) {
                List<String> reportPaths = reportPathManager.removeSession(sessionId);
                XWPFDocument targetDoc;
                try (FileInputStream fis = new FileInputStream(reportPaths.get(0))) {
                    targetDoc = new XWPFDocument(fis);
                }
                List<XWPFDocument> sourceDocs = new ArrayList<>();
                for (int i = 1; i < reportPaths.size(); i++) {
                    try (FileInputStream fis = new FileInputStream(reportPaths.get(i))) {
                        sourceDocs.add(new XWPFDocument(fis));
                    }
                }
                String label = relationId + "_" + IdUtil.fastSimpleUUID();
                mergedReportPath = filerepoProperties.getBasePath() + "/" + label + ".docx";
                // 调用合并方法
                DocxUtil.mergeDocx(targetDoc, sourceDocs, mergedReportPath, relationId);

            }
        } catch (Exception e) {
            log.error("生成FXY报告失败，开始清除相关缓存", e);

            if (relationId != null) {
                relationCounterRedisUtil.reset(relationId); // 清除计数缓存
            }
            if (sessionId != null) {
                reportPathManager.removeSession(sessionId); // 清除会话对应的报告路径
                SESSION_MAP.remove(relationId.toString()); // 清除会话映射
            }
        }

        return new ReportGenerationResult(reportPath, mergedReportPath, isLastModule);
    }

    /**
     * 处理单个模块的报告生成
     */
    @SuppressWarnings("checkstyle:ParameterNumber")
    private String processModule(ModuleType moduleType, String data,
        InputStream inputStream, String sessionId, Long relationId, Integer counter) throws Exception {
        String reportPath = null;
        String type = moduleType.getType();
        switch (moduleType) {

            case OTHER:
                reportPath = new OtherRender(sessionId, filerepoProperties, commonDataCache)
                    .createFXYDocument(data, inputStream, String.valueOf(relationId), counter, type);
                break;

            case PLATFORM_COMPANY_ATTACHMENTSECTION:
                reportPath = new AttachmentSectionRender(sessionId, filerepoProperties, commonDataCache)
                    .createFXYDocument(data, inputStream, String.valueOf(relationId), counter, type);
                break;

            case COVER:
                reportPath = new CoverRender(sessionId, filerepoProperties, commonDataCache)
                    .createFXYDocument(data, inputStream, String.valueOf(relationId), counter, type);
                break;

            case OPERATIONAL:
                reportPath = new OperationalRender(sessionId, filerepoProperties, commonDataCache)
                    .createFXYDocument(data, inputStream, String.valueOf(relationId), counter, type);
                break;

            case JUDICIAL:
                reportPath = new JudicialRender(sessionId, filerepoProperties, commonDataCache)
                    .createFXYDocument(data, inputStream, String.valueOf(relationId), counter, type);
                break;
            case BUSINESS:
                reportPath = new BusinessRender(sessionId, filerepoProperties, commonDataCache)
                    .createFXYDocument(data, inputStream, String.valueOf(relationId), counter, type);
                break;
            case TAX:
                reportPath = new TaxRender(sessionId, filerepoProperties, commonDataCache)
                    .createFXYDocument(data, inputStream, String.valueOf(relationId), counter, type);
                break;
            default:
                throw new UnsupportedOperationException("Unsupported module type: " + moduleType);
        }
        return reportPath;
    }

}
