package com.njcn.gather.icd.mapping.service.impl;


import com.njcn.gather.icd.mapping.component.*;
import com.njcn.gather.icd.mapping.pojo.bo.IcdToXmlGenerateResult;
import com.njcn.gather.icd.mapping.pojo.bo.analysis.IndexAnalysis;
import com.njcn.gather.icd.mapping.pojo.bo.analysis.ValidationResult;
import com.njcn.gather.icd.mapping.pojo.bo.icd.IcdDocument;
import com.njcn.gather.icd.mapping.pojo.bo.mapping.MappingDocument;
import com.njcn.gather.icd.mapping.pojo.bo.template.DefaultTemplate;
import com.njcn.gather.icd.mapping.pojo.dto.IcdToXmlGenerateCommand;
import com.njcn.gather.icd.mapping.pojo.enums.GenerateStatus;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.List;

@Service
public class IcdToXmlTaskAppService {
    private final IcdParserService icdParserService;
    private final DefaultTemplateLoader defaultTemplateLoader;
    private final IndexAnalysisService indexAnalysisService;
    private final IndexValidationService indexValidationService;
    private final MappingGenerationService mappingGenerationService;
    private final RuleBasedXmlMappingService ruleBasedXmlMappingService;
    private final MappingDocumentSerializer mappingDocumentSerializer;
    private final FileStorageService fileStorageService;
    private final IcdToXmlMappingService icdToXmlMappingService;
    private final JsonToXmlConversionService jsonToXmlConversionService;
    
    public IcdToXmlTaskAppService(IcdParserService icdParserService,
                                  DefaultTemplateLoader defaultTemplateLoader,
                                  IndexAnalysisService indexAnalysisService,
                                  IndexValidationService indexValidationService,
                                  MappingGenerationService mappingGenerationService,
                                  RuleBasedXmlMappingService ruleBasedXmlMappingService,
                                  MappingDocumentSerializer mappingDocumentSerializer,
                                  FileStorageService fileStorageService,
                                  IcdToXmlMappingService icdToXmlMappingService,
                                  JsonToXmlConversionService jsonToXmlConversionService) {
        this.icdParserService = icdParserService;
        this.defaultTemplateLoader = defaultTemplateLoader;
        this.indexAnalysisService = indexAnalysisService;
        this.indexValidationService = indexValidationService;
        this.mappingGenerationService = mappingGenerationService;
        this.ruleBasedXmlMappingService = ruleBasedXmlMappingService;
        this.mappingDocumentSerializer = mappingDocumentSerializer;
        this.fileStorageService = fileStorageService;
        this.icdToXmlMappingService = icdToXmlMappingService;
        this.jsonToXmlConversionService = jsonToXmlConversionService;
    }

    public IcdToXmlGenerateResult generateFromIcd(IcdToXmlGenerateCommand command) {
        IcdToXmlGenerateResult result = new IcdToXmlGenerateResult();
        try {
            // ========== 第一步：ICD → JSON ==========
            
            // 1. 解析 ICD
            IcdDocument icdDocument = icdParserService.parse(command.getFileBytes(), command.getFileName());
            result.setIedName(icdDocument.getIedName());
            result.setLdInst(icdDocument.getLdInst());

            // 2. 加载 DefaultCfg.txt和默认配置
            //DefaultTemplate template = defaultTemplateLoader.loadDefaultTemplateToXml();
            DefaultTemplate template = defaultTemplateLoader.load();
            result.getProblems().addAll(template.verify());

            InputStream templateStream = ruleBasedXmlMappingService.loadDefaultXmlFile();
            if(templateStream==null){result.getProblems().add("缺少默认xml配置文件");}
            List<InputStream> ruleStreams = ruleBasedXmlMappingService.loadDefaultRuleFile();
            if(ruleStreams==null){result.getProblems().add("缺少默认规则配置文件");}


            // 3. 分析索引候选
            IndexAnalysis indexAnalysis = indexAnalysisService.analyze(icdDocument, template);
            result.setIndexAnalysis(indexAnalysis);
            result.getProblems().addAll(indexAnalysis.getProblems());

            // 4. 如果没有提交任何绑定关系，则直接返回待匹配项
            if (command.getIndexSelection() == null || command.getIndexSelection().isEmpty()) {
                result.setStatus(GenerateStatus.NEED_INDEX_SELECTION);
                result.setMessage("索引配置缺失或不合法，请根据候选信息完成标签与数字索引的绑定后重新提交");
                return result;
            }

            // 5. 校验用户提交的绑定关系
            ValidationResult validationResult = indexValidationService.validate(indexAnalysis, command.getIndexSelection());
            if (!validationResult.isValid()) {
                result.setStatus(GenerateStatus.NEED_INDEX_SELECTION);
                result.setMessage("索引配置缺失或不合法，请根据候选信息完成标签与数字索引的绑定后重新提交");
                result.getProblems().addAll(validationResult.getProblems());
                return result;
            }

            // 6. 生成正式映射结构（JSON中间态）
            MappingDocument mappingDocument = mappingGenerationService.generate(
                    icdDocument,
                    template,
                    indexAnalysis,
                    command.getIndexSelection(),
                    command.getVersion(),
                    command.getAuthor()
            );
            result.setMappingDocument(mappingDocument);
            
            // 7. 序列化为JSON字符串（中间产物）
            String mappingJson = mappingDocumentSerializer.toPrettyJson(mappingDocument);

            // ========== 第二步：JSON → XML ==========
            
            // 8. 重新绑定正确索引
            IcdToXmlMappingService.IndexMappingConfig mappingConfig = icdToXmlMappingService.buildIndexMappingFromSelection(command.getIndexSelection());
            icdToXmlMappingService.setIndexMapping(mappingConfig);
            
            // 9. 从JSON转换为XML
            String xmlPath = jsonToXmlConversionService.convertFromJson(
                    mappingJson,
                    templateStream,
                    ruleStreams,
                    icdToXmlMappingService.getIndexMapping()
            );
            result.setSavedPath(xmlPath);

            result.setStatus(GenerateStatus.SUCCESS);
            result.setMessage("映射生成成功");
            return result;
        } catch (Exception ex) {
            result.setStatus(GenerateStatus.FAILED);
            result.setMessage("映射生成失败：" + ex.getMessage());
            result.getProblems().add(ex.getMessage());
            return result;
        }
    }

    /**
     * 直接从 JSON 字符串生成 XML 文件。
     * 
     * @param mappingJson MMS 映射 JSON 字符串（由 getIcdMmsJson 接口返回）
     * @return XML 生成结果
     */
    public IcdToXmlGenerateResult generateXmlFromJson(String mappingJson){
        IcdToXmlGenerateResult result = new IcdToXmlGenerateResult();
        try {
            // 1. 加载模板和规则文件
            InputStream templateStream = ruleBasedXmlMappingService.loadDefaultXmlFile();
            if (templateStream == null) {
                result.setStatus(GenerateStatus.FAILED);
                result.getProblems().add("缺少默认xml配置文件");
                result.setMessage("XML 生成失败：缺少默认xml配置文件");
                return result;
            }
            
            List<InputStream> ruleStreams = ruleBasedXmlMappingService.loadDefaultRuleFile();
            if (ruleStreams == null) {
                result.setStatus(GenerateStatus.FAILED);
                result.getProblems().add("缺少默认规则配置文件");
                result.setMessage("XML 生成失败：缺少默认规则配置文件");
                return result;
            }


            // 3. 从 JSON 转换为 XML
            String xmlPath = jsonToXmlConversionService.convertFromJson(
                    mappingJson,
                    templateStream,
                    ruleStreams,
                    icdToXmlMappingService.getIndexMapping()
            );
            
            result.setSavedPath(xmlPath);
            result.setStatus(GenerateStatus.SUCCESS);
            result.setMessage("XML 生成成功");
            return result;
        } catch (Exception ex) {
            result.setStatus(GenerateStatus.FAILED);
            result.setMessage("XML 生成失败：" + ex.getMessage());
            result.getProblems().add(ex.getMessage());
            return result;
        }
    }

}
