package com.seer.teach.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.seer.teach.admin.request.AddKnowledgePointUnitMappingReq;
import com.seer.teach.admin.request.KnowledgePointSimilarityCheckReq;
import com.seer.teach.admin.request.MergeKnowledgePointsReq;
import com.seer.teach.admin.response.KnowledgePointSimilarityCheckResp;
import com.seer.teach.admin.service.KnowledgePointSimilarityService;
import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.exception.CommonException;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.teacher.module.entity.KnowSummaryEntity;
import com.seer.teach.teacher.module.entity.KnowledgePointEntity;
import com.seer.teach.teacher.module.entity.MaterialEntity;
import com.seer.teach.teacher.module.entity.MergedKnowledgePointEntity;
import com.seer.teach.teacher.module.entity.UnitKnowMappingEntity;
import com.seer.teach.teacher.module.entity.UnitsEntity;
import com.seer.teach.teacher.module.entity.VersionsEntity;
import com.seer.teach.teacher.service.KnowSummaryService;
import com.seer.teach.teacher.service.KnowledgePointQueryService;
import com.seer.teach.teacher.service.KnowledgePointService;
import com.seer.teach.teacher.service.MaterialService;
import com.seer.teach.teacher.service.MergedKnowledgePointService;
import com.seer.teach.teacher.service.UnitKnowMappingService;
import com.seer.teach.teacher.service.VersionsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 知识点相似度检查服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class KnowledgePointSimilarityServiceImpl implements KnowledgePointSimilarityService {

    private final KnowledgePointService knowledgePointService;

    private final MergedKnowledgePointService mergedKnowledgePointService;

    private final KnowledgePointQueryService knowledgePointQueryService;

    private final KnowSummaryService knowSummaryService;

    private final MaterialService materialService;

    private final VersionsService versionsService;

    private final UnitKnowMappingService unitKnowMappingService;

    @Value("${zs.text.similarity.service.url:http://192.168.0.108:5000/text-similarity-batch}")
    private String textSimilarityServiceUrl;

    /**
     * 检查知识点相似度
     *
     * @param req 知识点相似度检查请求参数
     * @return 相似度检查结果
     */
    @Override
    public KnowledgePointSimilarityCheckResp checkKnowledgePointSimilarity(KnowledgePointSimilarityCheckReq req) {
        log.info("开始检查知识点相似度，知识点ID: {}, 阈值: {}", req.getKnowledgePointId(), req.getThreshold());

        // 1. 查询目标知识点信息
        KnowledgePointEntity targetKnowledgePoint;
        String knowledgePointName = req.getKnowledgePointName();
        String summary = req.getSummary();

        // 判断是新增知识点还是已有知识点
        if (req.getKnowledgePointId() != null && req.getKnowledgePointId() > 0) {
            // 已有知识点
            targetKnowledgePoint = knowledgePointService.getById(req.getKnowledgePointId());
            AssertUtils.notNull(targetKnowledgePoint, ResultCodeEnum.KNOW_NOT_EXIST);
        } else {
            // 新增知识点
            targetKnowledgePoint = new KnowledgePointEntity();
            targetKnowledgePoint.setKnowledgePointName(req.getKnowledgePointName());
            targetKnowledgePoint.setSubjectId(req.getSubjectId());
            targetKnowledgePoint.setGradeType(req.getGradeType());
        }

        // 2. 查询相邻年级和相同科目的知识点
        Collection<KnowledgePointEntity> allKnowledgePoints = getRelatedKnowledgePoints(targetKnowledgePoint);
        if (CollUtil.isEmpty(allKnowledgePoints)) {
            return new KnowledgePointSimilarityCheckResp();
        }
        log.info("查询到相邻年级和相同科目的知识点数量: {}", allKnowledgePoints.size());


        // 3. 构造请求数据并调用相似度计算接口
        Long startTime = System.currentTimeMillis();
        List<KnowledgePointSimilarityCheckResp.SimilarKnowledgePoint> similarityResults = calculateSimilarities(knowledgePointName, summary, allKnowledgePoints);
        log.info("相似度计算耗时：{}s", (System.currentTimeMillis() - startTime) / 1000);
        // 4. 过滤超过阈值的结果
        List<KnowledgePointSimilarityCheckResp.SimilarKnowledgePoint> filteredResults = similarityResults.stream()
                .filter(result -> Objects.nonNull(result.getSimilarity()) && result.getSimilarity() >= req.getThreshold())
                .collect(Collectors.toList());

        // 6. 构造响应结果
        KnowledgePointSimilarityCheckResp resp = new KnowledgePointSimilarityCheckResp();
        resp.setKnowledgePointId(req.getKnowledgePointId());
        resp.setKnowledgePointName(knowledgePointName);
        resp.setSimilarKnowledgePoints(filteredResults);

        log.info("知识点相似度检查完成，找到 {} 个相似知识点", filteredResults.size());
        return resp;
    }

    /**
     * 获取相关年级和相同科目的知识点
     *
     * @param targetKnowledgePoint 目标知识点
     * @return 相关知识点列表
     */
    private Collection<KnowledgePointEntity> getRelatedKnowledgePoints(KnowledgePointEntity targetKnowledgePoint) {
        // 获取目标知识点的年级ID
        Set<Integer> gradeIds = new HashSet<>();

        // 如果是已有知识点，获取其年级信息
        if (targetKnowledgePoint.getId() != null) {
            Integer targetGradeId = knowledgePointService.getGradeIdByKnowId(targetKnowledgePoint.getId());

            // 查询相邻年级
            // 这里需要根据具体业务逻辑确定相邻年级的计算方式
            // 暂时假设相邻年级为当前年级的前一个和后一个年级
            if (targetGradeId != null) {
                if (targetGradeId > 1) {
                    // 上一个年级
                    gradeIds.add(targetGradeId - 1);
                }
                // 当前年级
                gradeIds.add(targetGradeId);
                // 假设年级ID最大为12（高中三年级）
                if (targetGradeId < 12) {
                    // 下一个年级
                    gradeIds.add(targetGradeId + 1);
                }
            }
        } else if (Objects.nonNull(targetKnowledgePoint.getGradeType())) {
            // 如果是新增知识点，根据年级类型推断可能的年级范围
            // 小学(1): 1-6年级, 初中(2): 7-9年级, 高中(3): 10-12年级
            int startGrade = 1, endGrade = 6; // 默认小学
            switch (targetKnowledgePoint.getGradeType()) {
                case 1: // 小学
                    startGrade = 1;
                    endGrade = 6;
                    break;
                case 2: // 初中
                    startGrade = 7;
                    endGrade = 9;
                    break;
                case 3: // 高中
                    startGrade = 10;
                    endGrade = 12;
                    break;
            }

            // 添加当前学段的所有年级和相邻学段的部分年级
            for (int i = Math.max(1, startGrade - 1); i <= Math.min(12, endGrade + 1); i++) {
                gradeIds.add(i);
            }
        }

        // 查询知识点
        Collection<KnowledgePointEntity> knowledgePoints = knowledgePointQueryService.getKnowListByGradeIdsAndSubjectIdsOrElseEmpty(
                gradeIds,
                Collections.singleton(targetKnowledgePoint.getSubjectId()));

        if (CollectionUtil.isEmpty(knowledgePoints)) {
            knowledgePoints = knowledgePointQueryService.getKnowledgePointListBySubjectId(targetKnowledgePoint.getSubjectId());
            if (CollectionUtil.isEmpty(knowledgePoints)) {
                return Collections.emptyList();
            }
        }

        if (Objects.nonNull(targetKnowledgePoint.getId())) {
            return knowledgePoints.stream()
                    .filter(kp -> !Objects.equals(kp.getId(), targetKnowledgePoint.getId())) // 排除自身
                    .collect(Collectors.toList());
        }
        return knowledgePoints;
    }

    private List<KnowledgePointSimilarityCheckResp.SimilarKnowledgePoint> calculateSimilarities(
            String knowledgePointName, String summary,
            Collection<KnowledgePointEntity> allKnowledgePoints) {
        if (CollectionUtil.isEmpty(allKnowledgePoints)) {
            return Collections.emptyList();
        }
        if (StringUtils.isEmpty(knowledgePointName) || StringUtils.isEmpty(summary)) {
            return Collections.emptyList();
        }
        Map<Integer, KnowSummaryEntity> summaryMap = new HashMap<>();
        List<Integer> knowIds = allKnowledgePoints.stream().map(KnowledgePointEntity::getId).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(knowIds)) {
            List<KnowSummaryEntity> summaries = knowSummaryService.getListByKnowIds(knowIds);
            if (CollectionUtil.isNotEmpty(summaries)) {
                summaryMap = summaries.stream()
                        .collect(Collectors.toMap(KnowSummaryEntity::getKnowId, Function.identity()));
            }
        }
        try {
            // 构造目标文本（名称+总结）
            String targetText = knowledgePointName + " " + summary;
            // 构造请求数据
            JSONObject requestData = new JSONObject();
            requestData.set("text1", targetText);

            JSONArray text2List = new JSONArray();

            for (KnowledgePointEntity knowledgePoint : allKnowledgePoints) {
                JSONObject textObj = new JSONObject();
                textObj.set("id", knowledgePoint.getId());

                // 构造比较文本（名称+总结）
                String compareText = knowledgePoint.getKnowledgePointName();
                KnowSummaryEntity knowSummary = summaryMap.get(knowledgePoint.getId());
                if (Objects.nonNull(knowSummary) && StringUtils.isNotEmpty(knowSummary.getSummary())) {
                    compareText += "_" + knowSummary.getSummary();
                }
                textObj.set("text", compareText);
                text2List.add(textObj);
            }
            requestData.set("text2List", text2List);

            // 发送请求
            String url = textSimilarityServiceUrl;
            log.info("相似度计算的url:{}", url);
            HttpResponse response = HttpRequest.post(url).body(requestData.toString()).execute();

            if (!response.isOk()) {
                log.error("调用相似度计算接口失败，状态码: {}", response.getStatus());
                return Collections.emptyList();
            }
            // 获取所有知识点的教材和版本信息
            Collection<UnitKnowMappingEntity> unitKnowMappings = knowledgePointQueryService.getUnitKnowMappingListByKnowIds(knowIds);
            if (CollectionUtil.isEmpty(unitKnowMappings)) {
                return Collections.emptyList();
            }
            Map<Integer, Set<UnitKnowMappingEntity>> knowUnitMappings = unitKnowMappings.stream().collect(Collectors.groupingBy(UnitKnowMappingEntity::getKnowledgePointId, Collectors.toSet()));
            Set<Integer> unitIds = unitKnowMappings.stream().map(UnitKnowMappingEntity::getUnitId).collect(Collectors.toSet());
            if (CollectionUtil.isEmpty(unitIds)) {
                return Collections.emptyList();
            }
            Map<Integer, UnitsEntity> unitMap = knowledgePointQueryService.getUnitListByUnitIds(unitIds)
                    .stream()
                    .collect(Collectors.toMap(UnitsEntity::getId, Function.identity(), (v1, v2) -> v1));
            if (CollectionUtil.isEmpty(unitMap)) {
                return Collections.emptyList();
            }
            Map<Integer, List<UnitsEntity>> knowIdToUnits = new HashMap<>();

            for (UnitKnowMappingEntity mapping : unitKnowMappings) {
                Integer knowId = mapping.getKnowledgePointId();
                Integer unitId = mapping.getUnitId();

                UnitsEntity unit = unitMap.get(unitId);
                if (unit == null) {
                    continue;
                }
                knowIdToUnits.computeIfAbsent(knowId, k -> new ArrayList<>()).add(unit);
            }
            Set<Integer> materialIds = knowIdToUnits.values().stream()
                    .flatMap(List::stream).map(UnitsEntity::getMaterialId)
                    .collect(Collectors.toSet());

            List<MaterialEntity> materials = materialService.listByIds(materialIds);

            Map<Integer, MaterialEntity> materialMap = materials.stream().collect(Collectors.toMap(MaterialEntity::getId, Function.identity(), (old, newOne) -> newOne));
            Set<Integer> versionIds = materials.stream().map(MaterialEntity::getVersionId).collect(Collectors.toSet());
            Map<Integer, VersionsEntity> versionMap = versionsService.listByIds(versionIds)
                    .stream()
                    .collect(Collectors.toMap(VersionsEntity::getId, Function.identity(), (old, newOne) -> newOne));

            // 解析响应
            String responseBody = response.body();
            JSONArray resultArray = JSONUtil.parseArray(responseBody);

            Map<Integer, KnowledgePointEntity> pointEntityMap = allKnowledgePoints.stream().collect(Collectors.toMap(KnowledgePointEntity::getId, Function.identity(), (old, newOne) -> newOne));
            List<KnowledgePointSimilarityCheckResp.SimilarKnowledgePoint> results = new ArrayList<>();
            for (int i = 0; i < resultArray.size(); i++) {
                JSONObject resultObj = resultArray.getJSONObject(i);

                KnowledgePointSimilarityCheckResp.SimilarKnowledgePoint result = new KnowledgePointSimilarityCheckResp.SimilarKnowledgePoint();
                Integer knowId = resultObj.getInt("id");
                result.setKnowledgePointId(knowId);
                result.setSimilarity(resultObj.getDouble("similarity"));
                KnowledgePointEntity knowledgePointEntity = pointEntityMap.get(knowId);
                if (knowledgePointEntity != null) {
                    result.setKnowledgePointName(knowledgePointEntity.getKnowledgePointName());
                }
                KnowSummaryEntity knowSummaryEntity = summaryMap.get(knowId);
                if (knowSummaryEntity != null) {
                    result.setSummary(knowSummaryEntity.getSummary());
                }
                Set<UnitKnowMappingEntity> knowUnitMappingList = knowUnitMappings.get(knowId);

                if (CollectionUtil.isNotEmpty(knowUnitMappingList)) {
                    List<KnowledgePointSimilarityCheckResp.Book> books = new ArrayList<>();
                    for (UnitKnowMappingEntity unitKnowMapping : knowUnitMappingList) {
                        Integer unitId = unitKnowMapping.getUnitId();
                        if (Objects.isNull(unitId)) {
                            continue;
                        }
                        UnitsEntity unit = unitMap.get(unitId);
                        if (Objects.isNull(unit)) {
                            continue;
                        }
                        Integer materialId = unit.getMaterialId();
                        if (Objects.isNull(materialId)) {
                            continue;
                        }
                        MaterialEntity material = materialMap.get(unit.getMaterialId());
                        if (Objects.isNull(material)) {
                            continue;
                        }
                        VersionsEntity versionsEntity = versionMap.get(material.getVersionId());
                        if (Objects.isNull(versionsEntity)) {
                            continue;
                        }
                        KnowledgePointSimilarityCheckResp.Book book = new KnowledgePointSimilarityCheckResp.Book();
                        book.setBookName(material.getBookName());
                        book.setDocId(material.getDocId());
                        book.setIsStandardVersion(versionsEntity.getIsStandardVersion());
                        book.setUnitName(unit.getUnitName());
                        book.setVersionName(versionsEntity.getVersionName());
                        books.add(book);
                    }
                    result.setBooks(books);
                }
                results.add(result);
            }

            return results;
        } catch (Exception e) {
            log.error("调用相似度计算接口时发生异常", e);
            throw new RuntimeException("调用相似度计算接口时发生异常", e);
        }
    }

    /**
     * 合并知识点
     *
     * @param req 合并知识点请求参数
     * @return 合并结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean mergeKnowledgePoints(MergeKnowledgePointsReq req) {
        log.info("开始合并知识点，目标知识点ID: {}, 源知识点ID: {}", req.getTargetKnowledgePointId(), req.getSourceKnowledgePointId());

        Integer targetKnowledgePointId = req.getTargetKnowledgePointId();
        Integer sourceKnowledgePointId = req.getSourceKnowledgePointId();

        KnowledgePointEntity targetKnowledgePoint = knowledgePointService.getById(targetKnowledgePointId);
        AssertUtils.notNull(targetKnowledgePoint, ResultCodeEnum.KNOW_NOT_EXIST);

        KnowledgePointEntity sourceKnowledgePoint = knowledgePointService.getById(sourceKnowledgePointId);
        AssertUtils.notNull(sourceKnowledgePoint, ResultCodeEnum.KNOW_NOT_EXIST);
        AssertUtils.isTrue(sourceKnowledgePointId.intValue() != targetKnowledgePointId, ResultCodeEnum.KNOWLEDGE_POINT_MERGE_ERROR);

        // 记录合并信息（编辑时合并）
        String sourceKnowledgePointSummary = null;
        KnowSummaryEntity sourceSummary = knowSummaryService.getOneByKnowId(sourceKnowledgePoint.getId());
        if (Objects.nonNull(sourceSummary)) {
            sourceKnowledgePointSummary = sourceSummary.getSummary();
        }
        recordMergedKnowledgePoints(targetKnowledgePoint, req.getSourceUnitId(), sourceKnowledgePoint, sourceKnowledgePointSummary, MergedKnowledgePointEntity.MERGE_TYPE_EDIT);

        moveUnitMappings(sourceKnowledgePointId, req.getSourceUnitId(), targetKnowledgePointId);

        log.info("知识点合并完成，目标知识点ID: {}, 合并的知识点: {}", req.getTargetKnowledgePointId(), sourceKnowledgePointId);
        return true;
    }

    /**
     * 将源知识点的单元映射关系转移到目标知识点
     *
     * @param sourceKnowledgePointId 源知识点ID
     * @param sourceUnitId           源单元ID
     * @param targetKnowledgePointId 目标知识点ID
     */
    private void moveUnitMappings(Integer sourceKnowledgePointId, Integer sourceUnitId, Integer targetKnowledgePointId) {
        // 1. 获取源知识点的所有单元映射关系
        UnitKnowMappingEntity sourceMapping = knowledgePointQueryService.getUnitKnowMappingByUnitIdAndKnowId(sourceUnitId, sourceKnowledgePointId);

        if (Objects.isNull(sourceMapping)) {
            log.info("源知识点没有关联的单元映射关系");
            return;
        }

        // 2. 获取目标知识点已有的单元映射关系，避免重复映射
        Collection<UnitKnowMappingEntity> existingTargetMappings = knowledgePointQueryService.getUnitKnowMappingListByKnowIds(Collections.singletonList(targetKnowledgePointId));
        if (CollectionUtil.isEmpty(existingTargetMappings)) {
            return;
        }
        // 3. 保存新的映射关系
        UnitKnowMappingEntity newMapping = new UnitKnowMappingEntity();
        newMapping.setUnitId(sourceUnitId);
        newMapping.setKnowledgePointId(targetKnowledgePointId);
        newMapping.setSort(sourceMapping.getSort());
        newMapping.setIsChecked(0);
        newMapping.setCreateTime(LocalDateTime.now());
        unitKnowMappingService.save(newMapping);
        log.info("成功为目标知识点 {} 创建新的单元 {} 映射关系", targetKnowledgePointId, sourceUnitId);
        // 4. 删除源知识点的映射关系
        unitKnowMappingService.removeById(sourceMapping);
    }

    /**
     * 添加知识点并处理相似映射关系
     *
     * @param req 知识点请求对象，包含要添加的知识点信息
     * @return 是否添加成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addKnowledgePointUnitMappings(AddKnowledgePointUnitMappingReq req) {
        KnowledgePointEntity target = knowledgePointQueryService.getKnowledgePointByKnowId(req.getTargetKnowledgePointId());
        AssertUtils.notNull(target, ResultCodeEnum.KNOW_NOT_EXIST);
        UnitKnowMappingEntity unitKnowMapping = knowledgePointQueryService.getUnitKnowMappingByUnitIdAndKnowId(req.getSourceUnitId(), req.getTargetKnowledgePointId());
        if (unitKnowMapping == null) {
            UnitKnowMappingEntity mapping = new UnitKnowMappingEntity();
            mapping.setUnitId(req.getSourceUnitId());
            mapping.setKnowledgePointId(req.getTargetKnowledgePointId());
            mapping.setSort(req.getSort());
            mapping.setCreateTime(LocalDateTime.now());
            mapping.setIsChecked(0);

            boolean saved = unitKnowMappingService.save(mapping);
            if (saved) {
                log.info("添加知识点单元映射关系成功，单元ID：{}，知识点ID：{}", req.getSourceUnitId(), req.getTargetKnowledgePointId());
                KnowledgePointEntity sourceKnowledgePoint = new KnowledgePointEntity();
                sourceKnowledgePoint.setKnowledgePointName(req.getSourceKnowledgePointName());
                recordMergedKnowledgePoints(target, req.getSourceUnitId(), sourceKnowledgePoint, req.getSourceKnowledgePointSummary(), MergedKnowledgePointEntity.MERGE_TYPE_ADD);
            } else {
                log.error("添加知识点单元映射关系失败，单元ID：{}，知识点ID：{}", req.getSourceUnitId(), req.getTargetKnowledgePointId());
            }
            return saved;
        } else {
            throw new CommonException(ResultCodeEnum.KNOWLEDGE_POINT_EXISTS);
        }
    }

    private void recordMergedKnowledgePoints(KnowledgePointEntity targetKnowledgePoint, Integer sourceUnitId, KnowledgePointEntity sourceKnowledgePoint, String sourceKnowledgePointSummary, Integer mergeType) {
        // 查询目标信息
        Integer targetKnowledgePointId = targetKnowledgePoint.getId();

        KnowSummaryEntity targetSummary = knowSummaryService.getOneByKnowId(targetKnowledgePointId);
        Collection<Integer> targetUnitIds = knowledgePointQueryService.getUnitIdsByKnowId(targetKnowledgePointId);
        if (CollectionUtil.isEmpty(targetUnitIds)) {
            return;
        }
        List<UnitsEntity> targetUnits = knowledgePointQueryService.getUnitListByUnitIds(targetUnitIds);
        if (CollectionUtil.isEmpty(targetUnits)) {
            return;
        }
        Set<Integer> materialIds = targetUnits.stream().map(UnitsEntity::getMaterialId).collect(Collectors.toSet());
        Collection<MaterialEntity> targetMaterials = knowledgePointQueryService.getMaterialListByMaterialIds(materialIds);
        if (CollectionUtil.isEmpty(targetMaterials)) {
            return;
        }
        Set<Integer> targetVersionIds = targetMaterials.stream().map(MaterialEntity::getVersionId).collect(Collectors.toSet());
        Collection<VersionsEntity> targetVersions = knowledgePointQueryService.getVersionListByVersionIds(targetVersionIds);

        // 获取源信息
        UnitsEntity sourceUnit = knowledgePointQueryService.getUnitByUnitId(sourceUnitId);
        if (Objects.isNull(sourceUnit)) {
            return;
        }
        MaterialEntity sourceMaterial = knowledgePointQueryService.getMaterialByMaterialId(sourceUnit.getMaterialId());
        if (Objects.isNull(sourceMaterial)) {
            return;
        }
        VersionsEntity sourceVersion = knowledgePointQueryService.getVersionByVersionId(sourceMaterial.getVersionId());
        if (Objects.isNull(sourceVersion)) {
            return;
        }

        Map<Integer, Integer> targetUnitMaterialMapping = targetUnits.stream().collect(Collectors.toMap(UnitsEntity::getId, UnitsEntity::getMaterialId));
        Map<Integer, MaterialEntity> targetMaterialMapping = targetMaterials.stream().collect(Collectors.toMap(MaterialEntity::getId, Function.identity()));
        Map<Integer, Integer> targetUnitVersionMapping = targetMaterials.stream().collect(Collectors.toMap(MaterialEntity::getId, MaterialEntity::getVersionId));
        Map<Integer, VersionsEntity> targetVersionsMapping = targetVersions.stream().collect(Collectors.toMap(VersionsEntity::getId, Function.identity()));
        List<MergedKnowledgePointEntity> mergedKnowledgePoints = new ArrayList<>();
        for (UnitsEntity targetUnit : targetUnits) {
            MergedKnowledgePointEntity mergedKnowledgePoint = new MergedKnowledgePointEntity();
            mergedKnowledgePoint.setSourceUnitId(targetUnit.getId());
            mergedKnowledgePoint.setSourceUnitName(targetUnit.getUnitName());
            mergedKnowledgePoint.setSourceKnowledgePointName(sourceKnowledgePoint.getKnowledgePointName());
            mergedKnowledgePoint.setSourceKnowledgePointSummary(sourceKnowledgePointSummary);
            mergedKnowledgePoint.setSourceKnowledgePointId(sourceKnowledgePoint.getId());
            mergedKnowledgePoint.setSourceMaterialId(sourceMaterial.getId());
            mergedKnowledgePoint.setSourceMaterialName(sourceMaterial.getBookName());
            mergedKnowledgePoint.setSourceVersionId(sourceVersion.getId());
            mergedKnowledgePoint.setSourceVersionName(sourceVersion.getVersionName());

            // 设置目标单元相关信息
            Integer targetMaterialId = targetUnitMaterialMapping.get(targetUnit.getId());
            if (Objects.isNull(targetMaterialId)) {
                continue;
            }
            MaterialEntity targetMaterial = targetMaterialMapping.get(targetMaterialId);
            mergedKnowledgePoint.setTargetMaterialId(targetMaterial.getId());
            mergedKnowledgePoint.setTargetMaterialName(targetMaterial.getBookName());

            Integer versionId = targetUnitVersionMapping.get(targetMaterial.getVersionId());
            if (Objects.isNull(versionId)) {
                continue;
            }
            VersionsEntity versionsEntity = targetVersionsMapping.get(versionId);
            mergedKnowledgePoint.setTargetVersionId(versionsEntity.getId());
            mergedKnowledgePoint.setTargetVersionName(versionsEntity.getVersionName());
            mergedKnowledgePoint.setTargetUnitId(targetUnit.getId());
            mergedKnowledgePoint.setTargetUnitName(targetUnit.getUnitName());
            mergedKnowledgePoint.setTargetKnowledgePointSummary(targetSummary.getSummary());
            mergedKnowledgePoint.setTargetKnowledgePointName(targetKnowledgePoint.getKnowledgePointName());
            mergedKnowledgePoint.setTargetKnowledgePointId(targetKnowledgePoint.getId());
            mergedKnowledgePoint.setMergeType(mergeType);

            mergedKnowledgePoint.setSourceKnowledgePointSummary(sourceKnowledgePointSummary);

            mergedKnowledgePoints.add(mergedKnowledgePoint);
        }
        mergedKnowledgePointService.saveBatch(mergedKnowledgePoints);
        log.info("mergedKnowledgePoints save :{} ", mergedKnowledgePoints.size());
    }

    private void recordMergedKnowledgePoints(Integer targetKnowledgePointId, Integer sourceUnitId, String sourceKnowledgePointName, String sourceKnowledgePointSummary, Integer mergeType) {

        KnowledgePointEntity target = knowledgePointQueryService.getKnowledgePointByKnowId(targetKnowledgePointId);
        AssertUtils.notNull(target, ResultCodeEnum.KNOW_NOT_EXIST);
        KnowledgePointEntity sourceKnowledgePoint = new KnowledgePointEntity();
        sourceKnowledgePoint.setKnowledgePointName(sourceKnowledgePointName);

        recordMergedKnowledgePoints(target, sourceUnitId, sourceKnowledgePoint, sourceKnowledgePointSummary, mergeType);
    }
}