package com.qmth.distributed.print.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.distributed.print.business.bean.params.ObeCourseEvaluationParam;
import com.qmth.distributed.print.business.bean.result.ObeCourseEvaluationResult;
import com.qmth.distributed.print.business.entity.ObeCourseEvaluation;
import com.qmth.distributed.print.business.entity.ObeCourseOutline;
import com.qmth.distributed.print.business.entity.ObeCourseWeight;
import com.qmth.distributed.print.business.enums.CourseEvaluationTypeEnum;
import com.qmth.distributed.print.business.enums.CourseSettingTypeEnum;
import com.qmth.distributed.print.business.mapper.ObeCourseEvaluationMapper;
import com.qmth.distributed.print.business.service.ObeCourseEvaluationService;
import com.qmth.distributed.print.business.service.ObeCourseOutlineService;
import com.qmth.distributed.print.business.service.ObeCourseWeightService;
import com.qmth.teachcloud.common.base.BaseEntity;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程评价方式 服务实现类
 * </p>
 *
 * @author CaoZixuan
 * @since 2024-02-22
 */
@Service
public class ObeCourseEvaluationServiceImpl extends ServiceImpl<ObeCourseEvaluationMapper, ObeCourseEvaluation> implements
        ObeCourseEvaluationService {

    @Resource
    private ObeCourseOutlineService obeCourseOutlineService;

    @Resource
    private ObeCourseWeightService obeCourseWeightService;

    @Override
    public List<ObeCourseEvaluationResult> findCourseEvaluationList(Long obeCourseOutlineId) {
        ObeCourseOutline courseOutline = obeCourseOutlineService.getById(obeCourseOutlineId);
        if (Objects.isNull(courseOutline)) {
            throw ExceptionResultEnum.ERROR.exception("课程大纲不存在");
        }
        return this.baseMapper.findCourseEvaluationList(obeCourseOutlineId);
    }

    @Transactional
    @Override
    public void saveCourseEvaluation(ObeCourseEvaluationParam obeCourseEvaluationParam) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();

        Long id = obeCourseEvaluationParam.getId();
        Long obeCourseOutlineId = obeCourseEvaluationParam.getObeCourseOutlineId();
        String evaluation = obeCourseEvaluationParam.getEvaluation();
        String evaluationDesc = obeCourseEvaluationParam.getEvaluationDesc();
        CourseEvaluationTypeEnum type = obeCourseEvaluationParam.getType();
        ObeCourseOutline courseOutline = obeCourseOutlineService.getById(obeCourseOutlineId);
        if (Objects.isNull(courseOutline)) {
            throw ExceptionResultEnum.ERROR.exception("课程大纲不存在");
        }

        if (SystemConstant.longNotNull(id)) {
            // 编辑（只允许更改评价方式描述）
            ObeCourseEvaluation db = this.getById(id);
            if (Objects.isNull(db)) {
                throw ExceptionResultEnum.ERROR.exception("评价方式不存在");
            }
            if (!Objects.equals(db.getEvaluationDesc(), evaluationDesc)) {
                db.updateInfo(requestUser.getId());
                db.setEvaluationDesc(evaluationDesc);
                this.updateById(db);

                // 重置权重设置标识
                obeCourseOutlineService.update(
                        new UpdateWrapper<ObeCourseOutline>().lambda().eq(ObeCourseOutline::getId, obeCourseOutlineId).set(ObeCourseOutline::getWeightSettingSign, SystemConstant.getDbUuid()));
            }
        } else {
            // 新增
            if (this.count(new QueryWrapper<ObeCourseEvaluation>().lambda()
                    .eq(ObeCourseEvaluation::getObeCourseOutlineId, obeCourseOutlineId).eq(ObeCourseEvaluation::getEvaluation, evaluation)) > 0) {
                throw ExceptionResultEnum.ERROR.exception("评价方式重复");
            }
            ObeCourseEvaluation obeCourseEvaluation = new ObeCourseEvaluation();
            obeCourseEvaluation.setObeCourseOutlineId(obeCourseOutlineId);
            obeCourseEvaluation.setSchoolId(courseOutline.getSchoolId());
            obeCourseEvaluation.setType(type);
            obeCourseEvaluation.setEvaluation(evaluation);
            obeCourseEvaluation.setEvaluationDesc(evaluationDesc);
            obeCourseEvaluation.insertInfo(requestUser.getId());
            this.save(obeCourseEvaluation);
        }
    }

    @Transactional
    @Override
    public void deleteCourseEvaluation(Long id) {
        ObeCourseEvaluation obeCourseEvaluation = this.getById(id);
        if (Objects.nonNull(obeCourseEvaluation)) {
            if (CourseEvaluationTypeEnum.DEFAULT.equals(obeCourseEvaluation.getType())) {
                throw ExceptionResultEnum.ERROR.exception(String.format("[%s]的评价方式不能删除", CourseEvaluationTypeEnum.DEFAULT.getType()));
            }
            Long obeCourseOutlineId = obeCourseEvaluation.getObeCourseOutlineId();

            // 该评价方式涉及到的权重
            List<ObeCourseWeight> obeCourseWeightList = obeCourseWeightService.list(
                    new QueryWrapper<ObeCourseWeight>().lambda().eq(ObeCourseWeight::getObeCourseOutlineId, obeCourseOutlineId)
                            .eq(ObeCourseWeight::getEvaluationId, id));

            if (CollectionUtils.isNotEmpty(obeCourseWeightList)) {
                if (obeCourseWeightList.stream().anyMatch(ObeCourseWeight::getEnable)) {
                    // 该评价方式有被用到，删除所有权重设置
                    obeCourseOutlineService.clearCourseSetting(obeCourseOutlineId, CourseSettingTypeEnum.COURSE_EVALUATION);
                } else {
                    // 该评价方式没有用到，删除权重中涉及该评价方式的记录
                    obeCourseWeightService.removeByIds(
                            obeCourseWeightList.stream().map(BaseEntity::getId).collect(Collectors.toList()));
                }
            }
            this.removeById(id);
        }
    }

    @Transactional
    @Override
    public void createDefaultCourseEvaluation(Long obeCourseOutlineId) {
        // 创建默认评价方式
        CourseEvaluationTypeEnum type = CourseEvaluationTypeEnum.DEFAULT;
        ObeCourseEvaluationParam obeCourseEvaluationParam = new ObeCourseEvaluationParam();
        obeCourseEvaluationParam.setObeCourseOutlineId(obeCourseOutlineId);
        obeCourseEvaluationParam.setEvaluation(type.getName());
        obeCourseEvaluationParam.setEvaluationDesc(type.getValue());
        obeCourseEvaluationParam.setType(type);
        this.saveCourseEvaluation(obeCourseEvaluationParam);
    }
}