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.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.distributed.print.business.bean.params.ObeCourseOutlineParam;
import com.qmth.distributed.print.business.bean.result.CourseWeightSettingStatusResult;
import com.qmth.distributed.print.business.bean.result.DictionaryResult;
import com.qmth.distributed.print.business.bean.result.ObeCourseBasicInfoResult;
import com.qmth.distributed.print.business.bean.result.ObeCourseOutlineResult;
import com.qmth.distributed.print.business.entity.*;
import com.qmth.distributed.print.business.enums.CourseEvaluationTypeEnum;
import com.qmth.distributed.print.business.enums.CourseSettingTypeEnum;
import com.qmth.distributed.print.business.enums.ObeCourseOutlineCourseTypeEnum;
import com.qmth.distributed.print.business.enums.ObeCourseOutlineEvaluationEnum;
import com.qmth.distributed.print.business.mapper.ObeCourseOutlineMapper;
import com.qmth.distributed.print.business.service.*;
import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
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.service.BasicRoleDataPermissionService;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 课程大纲表 服务实现类
 * </p>
 *
 * @author CaoZixuan
 * @since 2024-06-05
 */
@Service
public class ObeCourseOutlineServiceImpl extends ServiceImpl<ObeCourseOutlineMapper, ObeCourseOutline> implements ObeCourseOutlineService {

    @Resource
    private BasicRoleDataPermissionService basicRoleDataPermissionService;

    @Resource
    private ObeCourseEvaluationService obeCourseEvaluationService;

    @Resource
    private ObeCourseDimensionService obeCourseDimensionService;

    @Resource
    private ObeCourseTargetService obeCourseTargetService;

    @Resource
    private ObeCourseWeightService obeCourseWeightService;

    @Resource
    private ObeCourseRequirementDimensionService obeCourseRequirementDimensionService;

    @Override
    public IPage<ObeCourseOutlineResult> findObeCourseOutlinePage(Long professionalId, Long cultureProgramId, Long courseId,
            String courseOutlineName, int pageNumber, int pageSize) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        courseOutlineName = SystemConstant.translateSpecificSign(courseOutlineName);
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(requestUser.getSchoolId(),
                requestUser.getId(), ServletUtil.getRequest().getServletPath());
        return baseMapper.findObeCourseOutlinePage(new Page<>(pageNumber, pageSize), professionalId, cultureProgramId,
                courseId, courseOutlineName, dpr);
    }

    @Override
    public void saveObeCourseOutline(ObeCourseOutlineParam obeCourseOutlineParams) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        String courseOutlineName = obeCourseOutlineParams.getCourseOutlineName();
        Long cultureProgramId = obeCourseOutlineParams.getCultureProgramId();
        Long semesterId = obeCourseOutlineParams.getSemesterId();
        Long courseId = obeCourseOutlineParams.getCourseId();
        ObeCourseOutlineEvaluationEnum evaluationMode = obeCourseOutlineParams.getEvaluationMode();
        ObeCourseOutlineCourseTypeEnum courseType = obeCourseOutlineParams.getCourseType();
        Long id = obeCourseOutlineParams.getId();

        ObeCourseOutline checkUnique = this.getOne(new QueryWrapper<ObeCourseOutline>().lambda()
                .eq(ObeCourseOutline::getCultureProgramId, cultureProgramId)
                .eq(ObeCourseOutline::getName, courseOutlineName).last(SystemConstant.LIMIT1));
        if (Objects.nonNull(checkUnique)) {
            if (!Objects.equals(checkUnique.getId(), id)) {
                throw new RuntimeException("该课程大纲名称已存在");
            }
        }

        ObeCourseOutline obeCourseOutline = new ObeCourseOutline();
        obeCourseOutline.setCultureProgramId(cultureProgramId);
        obeCourseOutline.setSemesterId(semesterId);
        obeCourseOutline.setCourseId(courseId);
        obeCourseOutline.setEvaluationMode(evaluationMode);
        obeCourseOutline.setCourseType(courseType);
        obeCourseOutline.setName(courseOutlineName);
        obeCourseOutline.setSchoolId(requestUser.getSchoolId());

        if (SystemConstant.longNotNull(id)) {
            // 编辑
            obeCourseOutline.setId(id);
            obeCourseOutline.updateInfo(requestUser.getId());
            this.updateById(obeCourseOutline);
        } else {
            // 新增
            obeCourseOutline.setWeightSetting(false);
            obeCourseOutline.insertInfo(requestUser.getId());
            obeCourseOutline.setUserId(requestUser.getId());
            this.save(obeCourseOutline);
            // 创建默认评价方式
            obeCourseEvaluationService.createDefaultCourseEvaluation(obeCourseOutline.getId());
        }
    }

    @Override
    public void removeObeCourseOutline(Long id) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        ObeCourseOutline obeCourseOutline = this.getById(id);
        if (Objects.nonNull(obeCourseOutline)) {
            if (!Objects.equals(obeCourseOutline.getUserId(), requestUser.getId())) {
                throw ExceptionResultEnum.ERROR.exception("只有课程大纲创建人可以删除该课程");
            }
        }
        // 删除知识点
        obeCourseDimensionService.remove(
                new QueryWrapper<ObeCourseDimension>().lambda().eq(ObeCourseDimension::getObeCourseOutlineId, id));
        // 删除课程目标
        obeCourseTargetService.remove(
                new QueryWrapper<ObeCourseTarget>().lambda().eq(ObeCourseTarget::getObeCourseOutlineId, id));

        // 删除指标和知识点关系
        obeCourseRequirementDimensionService.remove(new QueryWrapper<ObeCourseRequirementDimension>().lambda().eq(ObeCourseRequirementDimension::getObeCourseOutlineId, id));

        // 删除课程评价方式
        obeCourseEvaluationService.remove(
                new QueryWrapper<ObeCourseEvaluation>().lambda().eq(ObeCourseEvaluation::getObeCourseOutlineId, id));
        // 删除权重设置
        obeCourseWeightService.remove(
                new QueryWrapper<ObeCourseWeight>().lambda().eq(ObeCourseWeight::getObeCourseOutlineId, id));

        // 删除课程的大纲
        this.removeById(id);
    }

    @Transactional
    @Override
    public void removeAssessmentSetting(Long id) {
        // 删除课程评价方式
        obeCourseEvaluationService.remove(
                new QueryWrapper<ObeCourseEvaluation>().lambda().eq(ObeCourseEvaluation::getObeCourseOutlineId, id)
                        .eq(ObeCourseEvaluation::getType, CourseEvaluationTypeEnum.CUSTOM));
        // 删除权重设置
        obeCourseWeightService.deleteCourseWeight(id);
    }

    @Transactional
    @Override
    public void clearCourseSetting(Long obeCourseOutlineId, CourseSettingTypeEnum courseSettingTypeEnum) {
        if (courseSettingTypeEnum == CourseSettingTypeEnum.COURSE_DIMENSION) {// 删除知识点、目标设置
            SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
            Long requestUserId = requestUser.getId();

            obeCourseDimensionService.remove(new QueryWrapper<ObeCourseDimension>().lambda().eq(ObeCourseDimension::getObeCourseOutlineId, obeCourseOutlineId));

            // 清除指标点与知识点对应关系
            obeCourseRequirementDimensionService.remove(new QueryWrapper<ObeCourseRequirementDimension>().lambda()
                    .eq(ObeCourseRequirementDimension::getObeCourseOutlineId, obeCourseOutlineId));

            // 清除目标与指标点绑定关系（相当于提示指标点下的知识点已经换了请重新绑定）
            UpdateWrapper<ObeCourseTarget> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().eq(ObeCourseTarget::getObeCourseOutlineId, obeCourseOutlineId)
                    .set(ObeCourseTarget::getObeCultureProgramRequirementId, null).set(ObeCourseTarget::getUpdateId, requestUserId)
                    .set(ObeCourseTarget::getUpdateTime, System.currentTimeMillis());
            obeCourseTargetService.update(updateWrapper);

            UpdateWrapper<ObeCourseOutline> obeCourseOutlineWrapper = new UpdateWrapper<>();
            obeCourseOutlineWrapper.lambda().eq(ObeCourseOutline::getId, obeCourseOutlineId)
                    .set(ObeCourseOutline::getWeightSettingSign, SystemConstant.getDbUuid())
                    .set(ObeCourseOutline::getDimensionSign, SystemConstant.getDbUuid());
            this.update(obeCourseOutlineWrapper);
        } else {
            // 删除权重设置
            obeCourseWeightService.deleteCourseWeight(obeCourseOutlineId);
        }
    }

    @Override
    public CourseWeightSettingStatusResult findCourseWeightSettingStatus(Long obeCourseOutlineId) {
        CourseWeightSettingStatusResult result = new CourseWeightSettingStatusResult();
        ObeCourseOutline courseOutline = this.getById(obeCourseOutlineId);
        if (Objects.isNull(courseOutline)) {
            throw ExceptionResultEnum.ERROR.exception("教学课程不存在");
        }
        Boolean everSettingStatus = courseOutline.getWeightSetting();
        Boolean currenSettingStatus = obeCourseWeightService.count(new QueryWrapper<ObeCourseWeight>().lambda().eq(ObeCourseWeight::getObeCourseOutlineId, obeCourseOutlineId)) > 0;
        Long userId = courseOutline.getUserId();
        result.setEverSettingStatus(everSettingStatus);
        result.setCurrentSettingStatus(currenSettingStatus);
        result.setCourseCreateId(userId);
        return result;
    }

    @Override
    public ObeCourseBasicInfoResult findCourseBasicInfo(Long obeCourseOutlineId) {
        return this.baseMapper.findCourseBasicInfo(obeCourseOutlineId);
    }

    @Override
    public List<DictionaryResult> findCanChooseCultureProgram() {
        Long privilegeId = ServletUtil.getCurrentPrivilegeId();
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(privilegeId);
        return this.baseMapper.findCanChooseCultureProgram(dpr);
    }

    @Override
    public List<DictionaryResult> findCanChooseCourse(Long cultureProgramId) {
        return this.baseMapper.findCanChooseCourse(cultureProgramId);
    }
}
