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

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.teacher.util.ModificationLogUtils;
import com.seer.teach.teacher.module.entity.KnowledgePointEntity;
import com.seer.teach.teacher.module.entity.MaterialEntity;
import com.seer.teach.teacher.module.entity.UnitKnowMappingEntity;
import com.seer.teach.teacher.module.entity.UnitsEntity;
import com.seer.teach.teacher.module.mapper.KnowledgePointsMapper;
import com.seer.teach.teacher.module.mapper.MaterialMapper;
import com.seer.teach.teacher.module.mapper.UnitsMapper;
import com.seer.teach.teacher.service.KnowledgePointQueryService;
import com.seer.teach.teacher.service.KnowledgePointService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 知识点表 服务实现类
 * </p>
 *
 * @author Wang
 * @since 2025-10-09 15:20:36
 */
@Service
@RequiredArgsConstructor
public class KnowledgePointServiceImpl extends ServiceImpl<KnowledgePointsMapper, KnowledgePointEntity> implements KnowledgePointService {

    private final UnitsMapper unitsMapper;

    private final MaterialMapper materialMapper;

    private final KnowledgePointQueryService knowledgePointQueryService;

    @Override
    public boolean save(KnowledgePointEntity entity) {
        // 记录新增知识点日志
        boolean result = super.save(entity);
        if (result) {
            ModificationLogUtils.logModification(
                    1,
                    entity.getId(),
                    entity.getKnowledgePointName(),
                    1,
                    null,
                    entity,
                    StpUtil.getLoginIdAsInt()
            );
        }
        return result;
    }

    @Override
    public boolean updateById(KnowledgePointEntity entity) {
        // 获取修改前的数据
        KnowledgePointEntity before = knowledgePointQueryService.getKnowledgePointByKnowId(entity.getId());
        
        // 更新数据
        boolean result = super.updateById(entity);
        KnowledgePointEntity after = knowledgePointQueryService.getKnowledgePointByKnowId(entity.getId());
        // 记录修改日志
        if (result) {
            ModificationLogUtils.logModification(
                    1,
                    entity.getId(),
                    entity.getKnowledgePointName(),
                    2,
                    after,
                    entity,
                    StpUtil.getLoginIdAsInt()
            );
        }
        return result;
    }

    @Override
    public boolean removeById(Serializable id) {
        // 获取删除前的数据
        KnowledgePointEntity before = getById(id);
        
        // 删除数据
        boolean result = super.removeById(id);
        
        // 记录删除日志
        if (result && before != null) {
            ModificationLogUtils.logModification(
                    1, // 知识点类型
                    (Integer) id,
                    before.getKnowledgePointName(),
                    3, // 删除操作
                    before,
                    null,
                    StpUtil.getLoginIdAsInt()
            );
        }
        return result;
    }

    @Override
    public List<KnowledgePointEntity> getKnows(List<Integer> ids) {
        if(CollectionUtil.isEmpty(ids)){
            return Collections.emptyList();
        }
        Collection<Integer> knowIds = knowledgePointQueryService.getKnowIdListByUnitIds(ids);
        return list(new LambdaQueryWrapper<KnowledgePointEntity>()
                .in(KnowledgePointEntity::getId, knowIds)
                .orderByAsc(KnowledgePointEntity::getSort));
    }

    @Override
    public List<KnowledgePointEntity> getKnowsByIds(Collection<Integer> ids) {
        if(CollectionUtil.isEmpty(ids)){
            return Collections.emptyList();
        }
        return super.list(new LambdaQueryWrapper<KnowledgePointEntity>()
                .in(KnowledgePointEntity::getId, ids)
                .orderByAsc(KnowledgePointEntity::getId));
    }

    @Override
    public HashMap<Integer, Integer> getGradeIdWithKnowId(List<Integer> knowIds) {
        // 使用 Stream 去重
        List<Integer> distinctKnowIds = knowIds.stream()
                .distinct()
                .collect(Collectors.toList());
        List<KnowledgePointEntity> knows = listByIds(distinctKnowIds);

        Collection<UnitKnowMappingEntity> unitKnowMappings = knowledgePointQueryService.getUnitKnowMappingListByKnowIds(knowIds);

        if(CollectionUtil.isEmpty(unitKnowMappings)){
            return new HashMap<>();
        }

        Set<Integer> unitIds = unitKnowMappings.stream().map(UnitKnowMappingEntity::getUnitId).collect(Collectors.toSet());

        Map<Integer, Integer> unitKnowMappingMap = unitKnowMappings.stream().collect(Collectors.toMap(UnitKnowMappingEntity::getKnowledgePointId, UnitKnowMappingEntity::getUnitId));
        List<UnitsEntity> units = unitsMapper.selectByIds(unitIds);

        Map<Integer, Integer> unitIdToMaterialId = units.stream()
                .collect(Collectors.toMap(UnitsEntity::getId, UnitsEntity::getMaterialId));

        List<Integer> materialIds = units.stream()
                .map(UnitsEntity::getMaterialId)
                .distinct()
                .collect(Collectors.toList());

        List<MaterialEntity> materials = materialMapper.selectByIds(materialIds);

        Map<Integer, Integer> materialToGradeId = materials.stream()
                .collect(Collectors.toMap(MaterialEntity::getId, MaterialEntity::getGradeId));

        HashMap<Integer, Integer> result = new HashMap<>();

        for (KnowledgePointEntity know : knows) {
            Integer unitId = unitKnowMappingMap.get(know.getId());
            Integer bookId = unitIdToMaterialId.get(unitId);
            Integer gradeId = materialToGradeId.get(bookId);
            if (gradeId != null) {
                result.put(know.getId(), gradeId);
            }
        }
        return result;
    }


    @Override
    public Integer getGradeIdByKnowId(Integer knowId) {
        KnowledgePointEntity know = getById(knowId);
        AssertUtils.notNull(know, ResultCodeEnum.KNOW_NOT_EXIST);
        Collection<Integer> unitIds = knowledgePointQueryService.getUnitIdsByKnowId(knowId);
        if (CollectionUtil.isEmpty(unitIds)){
            return null;
        }
        List<UnitsEntity> units = unitsMapper.selectByIds(unitIds);
        if(CollectionUtil.isEmpty(units)){
            return null;
        }
        Set<Integer> materialIds = units.stream().map(UnitsEntity::getMaterialId).collect(Collectors.toSet());
        List<MaterialEntity> materials = materialMapper.selectByIds(materialIds);
        if(CollectionUtil.isEmpty(materials)){
            return null;
        }
        return materials.stream().findAny().get().getGradeId();
    }

}