package com.qmth.teachcloud.common.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.teachcloud.common.bean.params.BasicSemesterParams;
import com.qmth.teachcloud.common.bean.result.BasicSemesterResult;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicSemester;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.mapper.BasicSemesterMapper;
import com.qmth.teachcloud.common.service.BasicSemesterService;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * <p>
 * 学期字典表 服务实现类
 * </p>
 *
 * @author wangliang
 * @since 2021-10-28
 */
@Service
public class BasicSemesterServiceImpl extends ServiceImpl<BasicSemesterMapper, BasicSemester> implements BasicSemesterService {

    @Resource
    BasicSemesterService basicSemesterService;

    @Override
    public IPage<BasicSemesterResult> basicSemesterPage(Long schoolId, int pageNumber, int pageSize) {
        return this.baseMapper.findBasicSemesterPage(new Page<>(pageNumber, pageSize), schoolId, null);
    }

    @Transactional
    @Override
    public Long saveBasicSemester(BasicSemesterParams basicSemesterParams) throws IllegalAccessException {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        return basicSemesterService.saveBasicSemesterCommon(basicSemesterParams, sysUser.getSchoolId(), sysUser.getOrgId(),false);
    }

    /**
     * 保存公用
     *
     * @param basicSemesterParams
     * @param schoolId
     * @param orgId
     * @return
     * @throws IllegalAccessException
     */
    @Override
    @Transactional
    public Long saveBasicSemesterCommon(BasicSemesterParams basicSemesterParams, Long schoolId, Long orgId,boolean openApi) throws IllegalAccessException {
        SystemConstant.verifyDBFields(basicSemesterParams, basicSemesterParams.getClass());
        Long id = basicSemesterParams.getId();
        String semesterName = basicSemesterParams.getSemesterName();
        Long startTime = basicSemesterParams.getStartTime();
        Long endTime = basicSemesterParams.getEndTime();

        // 校验学期唯一性
        BasicSemester checkName = this.getOne(new QueryWrapper<BasicSemester>().lambda()
                .eq(BasicSemester::getEnable, true)
                .eq(BasicSemester::getSchoolId, schoolId)
                .eq(BasicSemester::getName, semesterName));
        if (Objects.nonNull(checkName) && !checkName.getId().equals(id)) {
            if (openApi){
                // 如果是开放接口（分布式印刷推学期给教研分析），就算没有教研分析学期id，只要名称一致就视为编辑
                id = checkName.getId();
            }else {
                throw ExceptionResultEnum.ERROR.exception("学期名称【" + semesterName + "】重复");
            }
        }
        if (SystemConstant.longNotNull(id)) {
            // 编辑
            BasicSemester old = this.getById(id);
            if (Objects.isNull(old) || old.getEnable().equals(false)) {
                throw ExceptionResultEnum.ERROR.exception("所选学期不存在或被禁用");
            }
            this.update(new UpdateWrapper<BasicSemester>().lambda()
                    .eq(BasicSemester::getId, id)
                    .set(BasicSemester::getName, semesterName)
                    .set(BasicSemester::getStartTime, startTime)
                    .set(BasicSemester::getEndTime, endTime));
        } else {
            // 新增
            id = SystemConstant.getDbUuid();
            BasicSemester basicSemester = new BasicSemester();
            basicSemester.setId(id);
            basicSemester.setEnable(true);
            basicSemester.setName(semesterName);
            basicSemester.setSchoolId(schoolId);
            basicSemester.setCode(null);
            basicSemester.setStartTime(startTime);
            basicSemester.setEndTime(endTime);
            basicSemester.setOrgId(orgId);

            QueryWrapper<BasicSemester> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(BasicSemester::getSchoolId, schoolId);
            List<BasicSemester> basicSemesters = this.list(queryWrapper);

            basicSemester.setInUsed(basicSemesters == null || basicSemesters.size() == 0);
            this.save(basicSemester);
        }
        return id;
    }

    @Transactional
    @Override
    public boolean deleteBasicSemesterById(Long id) {
        if (SystemConstant.longNotNull(id)) {
            if (this.baseMapper.countBasicExamBySemesterId(id) > 0) {
                throw ExceptionResultEnum.ERROR.exception("所选学期中包含考试 不能被删除");
            }
            return this.removeById(id);
        } else {
            return true;
        }
    }

    @Override
    public List<BasicSemester> list(Long schoolId, Boolean inUsed) {
        QueryWrapper<BasicSemester> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(BasicSemester::getSchoolId, schoolId).eq(BasicSemester::getEnable, true);
        if (Objects.nonNull(inUsed)) {
            queryWrapper.lambda().eq(BasicSemester::getInUsed, inUsed);
        }
        return this.list(queryWrapper);
    }

    @Transactional
    @Override
    public boolean setInUsed(Long id) {
        BasicSemester semester = this.getById(id);
        // 只能设置一个当前使用学期
        if (!semester.getInUsed()) {
            QueryWrapper<BasicSemester> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(BasicSemester::getSchoolId, semester.getSchoolId());
            List<BasicSemester> list = this.list(queryWrapper);
            if (!CollectionUtils.isEmpty(list)) {
                list = list.stream().map(m -> {
                    m.setInUsed(false);
                    return m;
                }).collect(Collectors.toList());
                this.updateBatchById(list);
            }
        }
        semester.setInUsed(!semester.getInUsed());
        return this.updateById(semester);
    }
}
