package jnpf.cultivate.v2.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.cultivate.mapper.CultivateIdentifyTableMapper;
import jnpf.cultivate.mapper.FtbCultivateCourseMapper;
import jnpf.cultivate.mapper.FtbCultivateLabelMapper;
import jnpf.cultivate.mapper.TeachingSkillMapper;
import jnpf.cultivate.v2.service.FtbCultivateLabelService;
import jnpf.entity.cultivate.CultivateIdentifyTable;
import jnpf.entity.cultivate.TeachingSkill;
import jnpf.enums.cultivate.CultivateIsSystemEnum;
import jnpf.model.cultivate.po.course.FtbCultivateCourse;
import jnpf.model.cultivate.po.label.FtbCultivateLabel;
import jnpf.model.cultivate.v2.label.dto.FtbCultivateLabelReq;
import jnpf.model.cultivate.v2.label.dto.FtbCultivateUpdateLabelReq;
import jnpf.model.cultivate.v2.label.vo.FtbCultivateLabelVo;
import jnpf.model.cultivate.v2.position.req.V2CultivateCommonCourseForAppReq;
import jnpf.util.ConstantUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 培训标签关联表 服务实现类
 */
@Service
public class FtbCultivateLabelServiceImpl extends ServiceImpl<FtbCultivateLabelMapper, FtbCultivateLabel> implements FtbCultivateLabelService {


    @Autowired
    private FtbCultivateCourseMapper ftbCultivateCourseMapper;

    @Autowired
    private CultivateIdentifyTableMapper cultivateIdentifyTableMapper;

    @Autowired
    private TeachingSkillMapper teachingSkillMapper;

    /**
     * 根据类型获取培训标签列表
     *
     * @param type 类型标识，用于筛选特定类型的培训标签
     * @return 返回符合条件的培训标签列表
     */
    @Override
    public List<FtbCultivateLabelVo> getList(Integer type, Integer source) {
        LambdaQueryWrapper<FtbCultivateLabel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FtbCultivateLabel::getType, type);
        queryWrapper.eq(source != null, FtbCultivateLabel::getSource, source);
        queryWrapper.eq(FtbCultivateLabel::getEnabledMark, 0); // 只查询未删除的记录
        queryWrapper.orderByDesc(FtbCultivateLabel::getSource);
        queryWrapper.orderByAsc(FtbCultivateLabel::getCreatorTime);
        List<FtbCultivateLabel> entityList = this.list(queryWrapper);
        if (CollUtil.isEmpty(entityList)) {
            return new ArrayList<>();
        }
        // 将实体列表转换为 VO 列表
        return entityList.stream()
                .map(this::entityToVo)
                .collect(Collectors.toList());
    }

    /**
     * 新增培训标签关联表
     *
     * @param req 包含新增培训标签所需数据的请求对象
     * @return 返回新增成功的培训标签信息
     */
    @Override
    public FtbCultivateLabelVo addData(FtbCultivateLabelReq req) {
        // 检查标签名称是否重复
        LambdaQueryWrapper<FtbCultivateLabel> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(FtbCultivateLabel::getName, req.getName());
        checkWrapper.eq(FtbCultivateLabel::getEnabledMark, 0);
        checkWrapper.eq(FtbCultivateLabel::getType, req.getType());
        if (this.count(checkWrapper) > 0) {
            throw new RuntimeException("标签名称已存在，请勿重复添加！");
        }

        // 创建实体对象
        FtbCultivateLabel entity = new FtbCultivateLabel();
        entity.setName(req.getName());
        entity.setSource(CultivateIsSystemEnum.NO.getCode()); // 使用常量替代硬编码
        entity.setType(req.getType());
        entity.setEnabledMark(0); // 设置为正常状态
        // 保存到数据库
        try {
            this.save(entity);
        } catch (Exception e) {
            throw new RuntimeException("保存标签失败，请稍后重试！");
        }
        // 返回 VO 对象
        return this.entityToVo(entity);
    }


    /**
     * 更新培训标签关联表信息
     *
     * @param id  主键ID，用于定位需要更新的培训标签记录
     * @param req 包含更新培训标签所需数据的请求对象，需通过@Valid注解进行校验
     * @return 返回更新后的培训标签信息
     */
    @Override
    public FtbCultivateLabelVo updateData(String id, FtbCultivateUpdateLabelReq req) {
        FtbCultivateLabel label = baseMapper.selectById(id);
        if (label == null || label.getEnabledMark() == 1) {
            throw new RuntimeException("标签不存在或已删除！");
        }

        // 检查标签名称是否重复
        LambdaQueryWrapper<FtbCultivateLabel> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(FtbCultivateLabel::getName, req.getName());
        checkWrapper.eq(FtbCultivateLabel::getEnabledMark, 0);
        checkWrapper.eq(FtbCultivateLabel::getType, label.getType());
        checkWrapper.ne(FtbCultivateLabel::getId, id);
        if (this.count(checkWrapper) > 0) {
            throw new RuntimeException("标签名称已存在！");
        }
        label.setName(req.getName());
        baseMapper.updateById(label);
        return this.entityToVo(label);
    }

    /**
     * 获取培训标签关联表信息
     *
     * @param id 主键ID，用于唯一标识一条培训标签记录
     * @return 返回对应的培训标签详细信息
     */
    @Override
    public FtbCultivateLabelVo getInfo(String id) {
        FtbCultivateLabel label = baseMapper.selectById(id);
        if (label == null || label.getEnabledMark() == 1) {
            throw new RuntimeException("标签不存在或已删除！");
        }
        return entityToVo(label);
    }

    /**
     * 删除培训标签关联表信息
     *
     * @param id 主键ID，用于定位需要删除的培训标签记录
     */
    @Override
    @Transactional
    public void deleteData(String id) {
        FtbCultivateLabel label = baseMapper.selectById(id);
        if (label == null || label.getEnabledMark() == 1) {
            throw new RuntimeException("标签不存在或已删除！");
        }
        if (label.getSource().equals(CultivateIsSystemEnum.YES.getCode())) {
            throw new RuntimeException("系统标签不能删除！");
        }

        if (label.getType().equals(1)) {
            //检查课程是否已经关联改标签
            LambdaQueryWrapper<FtbCultivateCourse> courseWrapper = new LambdaQueryWrapper<>();
            courseWrapper.eq(FtbCultivateCourse::getTypeId, id);
            courseWrapper.eq(FtbCultivateCourse::getEnableMark, 0);
            Long l = ftbCultivateCourseMapper.selectCount(courseWrapper);
            if (l > 0) {
                throw new RuntimeException("该标签已关联课程，请先解除关联关系！");
            }
        } else if (label.getType().equals(2)) {
            //检查鉴定表是否已经关联改标签
            LambdaQueryWrapper<CultivateIdentifyTable> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(CultivateIdentifyTable::getLabelId, id);
            queryWrapper.eq(CultivateIdentifyTable::getDeleteMark, 0); // 只检查有效的课程
            long count = cultivateIdentifyTableMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new RuntimeException("该标签已关联鉴定表，请先解除关联关系！");
            }
        } else if (label.getType().equals(3)) {
            LambdaQueryWrapper<TeachingSkill> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(TeachingSkill::getCategoryId, id);
            queryWrapper.eq(TeachingSkill::getDeleteMark, 0); // 只检查有效的课程
            long count = teachingSkillMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new RuntimeException("该标签已关联技能点，请先解除关联关系！");
            }
            teachingSkillMapper.update(null, new LambdaUpdateWrapper<TeachingSkill>()
                    .eq(TeachingSkill::getCategoryId, id)
                    .set(TeachingSkill::getCategoryId, ""));
        }

        label.setEnabledMark(1);
        baseMapper.updateById(label);
    }

    /**
     * 获取常用课程标签列表
     *
     * @param req 获取常用课程标签列表的请求参数
     * @return 返回常用课程标签列表
     */
    @Override
    public List<FtbCultivateLabelVo> commonCourseLabelList(V2CultivateCommonCourseForAppReq req) {
        return baseMapper.commonCourseLabelList(req);
    }

    @Override
    public Map<String, FtbCultivateLabel> getLabelMapByName(List<String> categoryNameList) {

        if (categoryNameList.isEmpty()) {
            return new HashMap<>();
        }
        // 查询分类信息
        LambdaQueryWrapper<FtbCultivateLabel> labelQuery = new LambdaQueryWrapper<FtbCultivateLabel>()
                .eq(FtbCultivateLabel::getType, 3)
                .eq(FtbCultivateLabel::getEnabledMark, ConstantUtil.NUM_FALSE)
                .in(FtbCultivateLabel::getName, categoryNameList);
        List<FtbCultivateLabel> labelList = this.list(labelQuery);
        return labelList.stream().collect(Collectors.toMap(FtbCultivateLabel::getName, Function.identity()));
    }

    /**
     * 将实体类转换为VO
     */
    private FtbCultivateLabelVo entityToVo(FtbCultivateLabel entity) {
        FtbCultivateLabelVo vo = new FtbCultivateLabelVo();
        vo.setId(entity.getId());
        vo.setName(entity.getName());
        vo.setSource(entity.getSource());
        vo.setType(entity.getType());
        return vo;
    }
}