package com.qmth.teachcloud.report.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.teachcloud.common.bean.auth.AuthBean;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicCourse;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.RoleTypeEnum;
import com.qmth.teachcloud.common.service.BasicCourseService;
import com.qmth.teachcloud.common.service.CommonCacheService;
import com.qmth.teachcloud.common.service.SysOrgService;
import com.qmth.teachcloud.common.util.ServletUtil;
import com.qmth.teachcloud.report.business.bean.result.TBExamCourseResult;
import com.qmth.teachcloud.report.business.entity.TBExamCourse;
import com.qmth.teachcloud.report.business.enums.PublishStatusEnum;
import com.qmth.teachcloud.report.business.enums.TestStatusEnum;
import com.qmth.teachcloud.report.business.mapper.TBExamCourseMapper;
import com.qmth.teachcloud.report.business.service.TBExamCourseService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 考试科目表 服务实现类
 * </p>
 *
 * @author wangliang
 * @since 2021-06-02
 */
@Service
public class TBExamCourseServiceImpl extends ServiceImpl<TBExamCourseMapper, TBExamCourse> implements TBExamCourseService {

    @Resource
    TBExamCourseMapper tbExamCourseMapper;

    @Resource
    BasicCourseService basicCourseService;

    @Resource
    SysOrgService sysOrgService;

    @Resource
    CommonCacheService commonCacheService;

    @Override
    public boolean verifyExamCourseCantRun(Long examId, Long schoolId, String courseCode, String courseName) {

        QueryWrapper<BasicCourse> schoolCourseQuery = new QueryWrapper<>();
        schoolCourseQuery.lambda()
                .eq(BasicCourse::getSchoolId, schoolId)
                .eq(BasicCourse::getCode, courseCode);
        if (SystemConstant.strNotNull(courseName)){
            schoolCourseQuery.lambda().eq(BasicCourse::getName, courseName);
        }
        List<BasicCourse> tbSchoolCourseList = basicCourseService.list(schoolCourseQuery);
        if (tbSchoolCourseList.size() != 1) {
            throw ExceptionResultEnum.ERROR.exception("学校课程基础数据异常");
        }

        QueryWrapper<TBExamCourse> examCourseQuery = new QueryWrapper<>();
        examCourseQuery.lambda()
                .eq(TBExamCourse::getExamId, examId)
                .eq(TBExamCourse::getCourseCode, courseCode);
        if (SystemConstant.strNotNull(courseName)){
            examCourseQuery.lambda().eq(TBExamCourse::getCourseName, courseName);
        }
        List<TBExamCourse> tbExamCourseList = this.list(examCourseQuery);
        if (tbExamCourseList.size() != 1) {
            throw ExceptionResultEnum.ERROR.exception("考试课程基础数据异常");
        }
        TBExamCourse tbExamCourse = tbExamCourseList.get(0);
        TestStatusEnum testStatusEnum = tbExamCourse.getTestStatus();
        PublishStatusEnum publishStatusEnum = tbExamCourse.getPublishStatus();
        return testStatusEnum.equals(TestStatusEnum.TEST) || testStatusEnum.equals(TestStatusEnum.CHECKED) ||
                publishStatusEnum.equals(PublishStatusEnum.PUBLISH);
    }

    @Override
    public List<String> findEffectiveByExamId(Long examId, String courseCode) {
        List<PublishStatusEnum> publishStatusEnumList = new ArrayList<>();
        publishStatusEnumList.add(PublishStatusEnum.UN_COMPUTE);
        publishStatusEnumList.add(PublishStatusEnum.WILL_COMPUTE);
        publishStatusEnumList.add(PublishStatusEnum.COMPUTING);
        publishStatusEnumList.add(PublishStatusEnum.UN_PUBLISH);

        List<TBExamCourse> effectiveCourseList = this.list(new QueryWrapper<TBExamCourse>().lambda()
                .eq(TBExamCourse::getExamId, examId)
                .eq(TBExamCourse::getTestStatus, TestStatusEnum.UN_TEST)
                .in(TBExamCourse::getPublishStatus, publishStatusEnumList));

        if (effectiveCourseList.size() == 0) {
            throw ExceptionResultEnum.ERROR.exception("该考试目前没有任何课程可以分析");
        }
        List<String> effectCourseCodeList = new ArrayList<>();
        if (courseCode != null && courseCode.length() > 0) {
            if (!effectiveCourseList.stream().map(TBExamCourse::getCourseCode).collect(Collectors.toList()).contains(courseCode)) {
                throw ExceptionResultEnum.ERROR.exception("课程【" + courseCode + "】无法进行分析");
            }
            effectCourseCodeList.add(courseCode);
        } else {
            effectCourseCodeList = effectiveCourseList.stream().map(TBExamCourse::getCourseCode).collect(Collectors.toList());
        }
        return effectCourseCodeList;
    }

    @Override
    public List<TBExamCourseResult> findCourseList(Long schoolId, Long examId, boolean inspect, Boolean absent, Boolean current, PublishStatusEnum status) {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        List<Long> collegeIds = sysOrgService.findCollegeIds(sysUser.getOrgId());
        AuthBean authBean = commonCacheService.userAuthCache(sysUser.getId());
        //院长开课学院不过滤，学校管理员不过滤，(院长考查学院过滤，教务老师过滤)
        boolean filter = true;
        if (Objects.nonNull(authBean) && Objects.nonNull(authBean.getRoleList()) && authBean.getRoleList().get(0).getType() == RoleTypeEnum.SCHOOL_ADMIN) {
            filter = false;
        } else if (Objects.nonNull(authBean) && Objects.nonNull(authBean.getRoleList()) && authBean.getRoleList().get(0).getType() == RoleTypeEnum.PRESIDENT && !inspect) {
            filter = false;
        }
        if (Objects.nonNull(collegeIds) && collegeIds.size() > 0) {
            return tbExamCourseMapper.findCourseList(schoolId, examId, inspect, collegeIds, filter, absent, current, Objects.nonNull(status) ? status.name() : null);
        } else {
            // TODO: 2022/1/8 临时针对考察学院的考察课程考试分析的更改要之后要前端配合改
            absent = false;
            current = true;
            return tbExamCourseMapper.findCourseList(schoolId, examId, inspect, Objects.nonNull(sysUser.getOrgId()) ? Arrays.asList(sysUser.getOrgId()) : null, filter, absent, current, Objects.nonNull(status) ? status.name() : null);
        }
    }

    /**
     * 查询科目信息
     *
     * @param schoolId
     * @param examId
     * @return
     */
    @Override
    public List<TBExamCourseResult> findCourseList(Long schoolId, Long examId, Boolean absent, Boolean current, PublishStatusEnum status) {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        return tbExamCourseMapper.findCourseListByTeacherId(schoolId, examId, sysUser.getId(), absent, current, Objects.nonNull(status) ? status.name() : null);
    }

    @Transactional
    @Override
    public void createCourse(Long schoolId, Long examId, String courseCode, String courseName, String paperType, String teachCollegeName) {
        Long teachCollegeId = sysOrgService.searchOrInsert(schoolId, teachCollegeName);
        List<TBExamCourse> tbExamCourseList = this.list(new QueryWrapper<TBExamCourse>().lambda()
                .eq(TBExamCourse::getExamId, examId)
                .eq(TBExamCourse::getSchoolId, schoolId)
                .eq(TBExamCourse::getCourseCode, courseCode)
                .eq(TBExamCourse::getPaperType, paperType));
        if (tbExamCourseList.size() > 0) {
            // 编辑
            TBExamCourse tbExamCourse = tbExamCourseList.get(0);
            if (this.verifyExamCourseCantRun(examId, schoolId, courseCode, null)){
                throw ExceptionResultEnum.ERROR.exception("考试id【" + examId + "】，课程编号为【" + courseCode + "】的课程试卷已经发布或检查，无法更新");
            }
            if (!Objects.equals(courseName,tbExamCourse.getCourseName()) ||
                    !Objects.equals(paperType,tbExamCourse.getPaperType()) ||
                    !Objects.equals(teachCollegeName,tbExamCourse.getTeachCollegeName())){
                tbExamCourse.setOpenDataMd5(null);
            }
            tbExamCourse.setPaperType(paperType);
            tbExamCourse.setCourseName(courseName);
            tbExamCourse.setTeachCollegeName(teachCollegeName);
            this.updateById(tbExamCourse);
        }else {
            // 新增
            TBExamCourse tbExamCourse = new TBExamCourse();
            tbExamCourse.setId(SystemConstant.getDbUuid());
            tbExamCourse.setSchoolId(schoolId);
            tbExamCourse.setExamId(examId);
            tbExamCourse.setCourseCode(courseCode);
            tbExamCourse.setCourseName(courseName);
            tbExamCourse.setPaperType(paperType);
            tbExamCourse.setTestStatus(TestStatusEnum.UN_TEST);
            tbExamCourse.setPublishStatus(PublishStatusEnum.UN_COMPUTE);
            tbExamCourse.setTeachCollegeId(teachCollegeId);
            tbExamCourse.setTeachCollegeName(teachCollegeName);
            this.save(tbExamCourse);
        }
    }

    @Override
    public boolean checkFinishCalculate(Long schoolId, Long examId, String courseCode) {
        TBExamCourse tbExamCourse = this.getOne(new QueryWrapper<TBExamCourse>().lambda()
                .eq(TBExamCourse::getSchoolId,schoolId)
                .eq(TBExamCourse::getExamId,examId)
                .eq(TBExamCourse::getCourseCode,courseCode));
        if (Objects.isNull(tbExamCourse)){
            throw ExceptionResultEnum.ERROR.exception("未找到基础分析课程");
        }
        return !PublishStatusEnum.UN_COMPUTE.equals(tbExamCourse.getPublishStatus());
    }
}
