package com.nbport.zgwl.manifest.handler;

import cn.hutool.core.util.StrUtil;
import com.nbport.zgwl.exception.ServiceException;
import com.nbport.zgwl.manifest.dto.ContractTemplateDto;
import com.nbport.zgwl.manifest.dto.TemplateOrgOptionDto;
import com.nbport.zgwl.manifest.dto.TemplateVariableMappingDto;
import com.nbport.zgwl.manifest.utils.ManifestJsonUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 模板数据处理器
 *
 * 负责：
 * 1. 保存前清洗数据
 * 2. 保存前校验数据
 * 3. 查询后把 JSON 文本转成前端需要的列表
 */
@Component
public class ContractTemplateDataHandler {

    /** 保存前数据清洗（去空格、去重、自动计算变量数和发布范围文本） */
    public void normalizeBeforeSave(ContractTemplateDto template) {
        template.setTemplateName(StrUtil.trim(template.getTemplateName()));
        template.setSource(StrUtil.trim(template.getSource()));
        template.setContractType(StrUtil.trim(template.getContractType()));
        template.setVersion(StrUtil.trim(template.getVersion()));
        template.setDescription(StrUtil.trim(template.getDescription()));
        template.setUsageTip(StrUtil.trim(template.getUsageTip()));
        template.setTemplateFileName(StrUtil.trim(template.getTemplateFileName()));
        template.setTemplateFilePath(StrUtil.trim(template.getTemplateFilePath()));

        List<String> publishOrgIds = template.getPublishOrgIds() == null ? new ArrayList<>() : template.getPublishOrgIds();
        List<String> publishOrgNames = template.getPublishOrgNames() == null ? new ArrayList<>() : template.getPublishOrgNames();
        template.setPublishOrgIds(
                publishOrgIds.stream()
                        .filter(StrUtil::isNotBlank)
                        .map(StrUtil::trim)
                        .distinct()
                        .collect(Collectors.toList())
        );
        template.setPublishOrgNames(
                publishOrgNames.stream()
                        .filter(StrUtil::isNotBlank)
                        .map(StrUtil::trim)
                        .distinct()
                        .collect(Collectors.toList())
        );

        List<TemplateVariableMappingDto> mappings = template.getVariableMappings() == null ? new ArrayList<>() : template.getVariableMappings();
        mappings = mappings.stream()
                .filter(Objects::nonNull)
                .map(item -> new TemplateVariableMappingDto(
                        StrUtil.blankToDefault(item.getId(), "var_" + System.nanoTime()),
                        StrUtil.trim(item.getVariableKey()),
                        StrUtil.trim(item.getBindField())
                ))
                .filter(item -> StrUtil.isNotBlank(item.getVariableKey()) || StrUtil.isNotBlank(item.getBindField()))
                .collect(Collectors.toList());
        template.setVariableMappings(mappings);
        template.setVariables(
                mappings.stream()
                        .map(TemplateVariableMappingDto::getVariableKey)
                        .filter(StrUtil::isNotBlank)
                        .distinct()
                        .collect(Collectors.toList())
        );
        template.setVariableCount(template.getVariables().size());
        template.setPublishScopeText(String.join("、", template.getPublishOrgNames()));
    }

    /** 保存前数据校验（必填项校验、变量映射校验） */
    public void validateForSave(ContractTemplateDto template) {
        if (StrUtil.isBlank(template.getTemplateName())) {
            throw new ServiceException("范本名称不能为空");
        }
        if (StrUtil.isBlank(template.getSource())) {
            throw new ServiceException("范本类型不能为空");
        }
        if (StrUtil.isBlank(template.getContractType())) {
            throw new ServiceException("合同类型不能为空");
        }
        if (StrUtil.isBlank(template.getVersion())) {
            throw new ServiceException("版本号不能为空");
        }
        if (StrUtil.isBlank(template.getTemplateFileName()) || StrUtil.isBlank(template.getTemplateFilePath())) {
            throw new ServiceException("请先上传 Word 模板文件");
        }
        if (template.getPublishOrgIds() == null || template.getPublishOrgIds().isEmpty()) {
            throw new ServiceException("发布范围不能为空");
        }
        if (template.getVariableMappings() == null || template.getVariableMappings().isEmpty()) {
            throw new ServiceException("请至少维护一个变量映射");
        }
        for (TemplateVariableMappingDto mapping : template.getVariableMappings()) {
            if (StrUtil.isBlank(mapping.getVariableKey())) {
                throw new ServiceException("模板变量名称不能为空");
            }
            if (StrUtil.isBlank(mapping.getBindField())) {
                throw new ServiceException("模板变量【" + mapping.getVariableKey() + "】尚未绑定业务字段");
            }
        }
    }

    /** 查询后将 JSON 文本转成前端需要的列表结构 */
    public void fillUiFields(ContractTemplateDto template) {
        if (template == null) {
            return;
        }
        template.setPublishOrgIds(ManifestJsonUtils.parseStringList(template.getPublishOrgIdsJson()));
        template.setPublishOrgNames(ManifestJsonUtils.parseStringList(template.getPublishOrgNamesJson()));
        template.setVariableMappings(
                ManifestJsonUtils.parseList(
                        template.getVariableMappingsJson(),
                        new com.alibaba.fastjson2.TypeReference<List<TemplateVariableMappingDto>>() {
                        }
                )
        );
        template.setVariables(
                template.getVariableMappings().stream()
                        .map(TemplateVariableMappingDto::getVariableKey)
                        .filter(StrUtil::isNotBlank)
                        .distinct()
                        .collect(Collectors.toList())
        );
        template.setVariableCount(template.getVariables().size());
        template.setPublishScopeText(String.join("、", template.getPublishOrgNames()));
    }

    /** 批量填充 UI 字段 */
    public void fillUiFields(List<ContractTemplateDto> templates) {
        if (templates == null) {
            return;
        }
        templates.forEach(this::fillUiFields);
    }

    /** 根据 id 批量填充发布范围 orgName（将 id 转为对应的组织名称） */
    public void fillOrgNamesByIds(ContractTemplateDto template, List<TemplateOrgOptionDto> orgOptions) {
        if (template.getPublishOrgIds() == null) {
            template.setPublishOrgNames(new ArrayList<>());
            return;
        }
        List<String> names = new ArrayList<>();
        for (String orgId : template.getPublishOrgIds()) {
            TemplateOrgOptionDto option = orgOptions.stream()
                    .filter(item -> Objects.equals(item.getOrgId(), orgId))
                    .findFirst()
                    .orElse(null);
            if (option != null) {
                names.add(option.getOrgName());
            }
        }
        template.setPublishOrgNames(names);
        template.setPublishScopeText(String.join("、", names));
    }
}
