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.obe.cultureProgram.ObeCultureProgramDescriptionParam;
import com.qmth.distributed.print.business.bean.result.obe.cultureProgram.CultureProgramResult;
import com.qmth.distributed.print.business.entity.*;
import com.qmth.distributed.print.business.mapper.ObeCultureProgramMapper;
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.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p>
 * 培养方案 服务实现类
 * </p>
 *
 * @author xf
 * @since 2024-06-05
 */
@Service
public class ObeCultureProgramServiceImpl extends ServiceImpl<ObeCultureProgramMapper, ObeCultureProgram> implements ObeCultureProgramService {

    @Resource
    private ObeCultureProgramTargetService obeCultureProgramTargetService;
    @Resource
    private ObeRequirementTargetMatrixService obeRequirementTargetMatrixService;
    @Resource
    private ObeCultureProgramCourseService obeCultureProgramCourseService;
    @Resource
    private ObeCultureProgramRequirementService obeCultureProgramRequirementService;
    @Resource
    private ObeCourseRequirementMatrixService obeCourseRequirementMatrixService;
    @Resource
    private BasicRoleDataPermissionService basicRoleDataPermissionService;

    @Override
    public IPage<CultureProgramResult> pageData(Page<CultureProgramResult> page, Long professionalId, String name) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(schoolId, requestUser.getId(), ServletUtil.getRequest().getServletPath());
        return this.baseMapper.pageData(page, schoolId, professionalId, name, dpr);
    }

    @Transactional
    @Override
    public boolean saveData(ObeCultureProgram obeCultureProgram) {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();

        ObeCultureProgram checkObeCultureProgram = this.getBySchoolIdAndName(obeCultureProgram.getProfessionalId(), obeCultureProgram.getName());
        if (obeCultureProgram.getId() == null) {
            if (checkObeCultureProgram != null) {
                throw ExceptionResultEnum.ERROR.exception("培养方案名称已存在");
            }
            obeCultureProgram.setSchoolId(sysUser.getSchoolId());
            obeCultureProgram.insertInfo(sysUser.getId());
            if (this.save(obeCultureProgram)) {
                obeCultureProgramRequirementService.initRequirement(obeCultureProgram.getId());
                this.updateRequirementCount(obeCultureProgram.getId());
            }
            return true;
        } else {
            if (checkObeCultureProgram != null && !checkObeCultureProgram.getId().equals(obeCultureProgram.getId())) {
                throw ExceptionResultEnum.ERROR.exception("培养方案名称已存在");
            }
            obeCultureProgram.updateInfo(sysUser.getId());
            return this.updateById(obeCultureProgram);
        }
    }

    @Transactional
    @Override
    public boolean delete(Long id) {
        // 删除培养方案
        this.removeById(id);
        // 删除培养目标
        obeCultureProgramTargetService.removeByCultureProgramId(id);
        // 删除毕业要求
        obeCultureProgramRequirementService.removeByCultureProgramId(id);
        // 删除培养目标与毕业要求关系矩阵
        obeRequirementTargetMatrixService.removeMatrixByCondition(new ObeRequirementTargetMatrix(id, null, null));
        // 删除课程体系
        obeCultureProgramCourseService.removeByCultureProgramId(id);
        // 删除课程毕业要求关系矩阵
        obeCourseRequirementMatrixService.removeMatrixByCondition(new ObeCourseRequirementMatrix(id, null, null, null));
        return true;
    }

    @Transactional
    @Override
    public boolean copy(Long id) {
        // 复制培养方案
        Long obeCultureProgramNewId = this.copyByCultureProgramId(id);
        // 复制课程目标
        Map<Long, Long> targetIdMap = obeCultureProgramTargetService.copyByCultureProgramId(id, obeCultureProgramNewId);
        // 复制毕业要求
        Map<Long, Long> requirementIdMap = obeCultureProgramRequirementService.copyByCultureProgramId(id, obeCultureProgramNewId);
        // 复制培养目标与毕业要求关系矩阵
        obeRequirementTargetMatrixService.copyByCultureProgramId(id, obeCultureProgramNewId, targetIdMap, requirementIdMap);
        // 复制课程体系
        Map<Long, Long> courseIdMap = obeCultureProgramCourseService.copyByCultureProgramId(id, obeCultureProgramNewId);
        // 复制课程毕业要求关系矩阵
        obeCourseRequirementMatrixService.copyByCultureProgramId(id, obeCultureProgramNewId, requirementIdMap, courseIdMap);
        return true;
    }

    @Override
    public ObeCultureProgram getBySchoolIdAndName(Long schoolId, String name) {
        QueryWrapper<ObeCultureProgram> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ObeCultureProgram::getSchoolId, schoolId)
                .eq(ObeCultureProgram::getName, name);
        return this.getOne(queryWrapper);
    }

    @Override
    public void updateTargetCount(Long cultureProgramId) {
        QueryWrapper<ObeCultureProgramTarget> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ObeCultureProgramTarget::getCultureProgramId, cultureProgramId);

        UpdateWrapper<ObeCultureProgram> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(ObeCultureProgram::getTargetCount, obeCultureProgramTargetService.count(queryWrapper))
                .eq(ObeCultureProgram::getId, cultureProgramId);
        this.update(updateWrapper);
    }

    @Override
    public void updateRequirementCount(Long cultureProgramId) {
        QueryWrapper<ObeCultureProgramRequirement> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ObeCultureProgramRequirement::getCultureProgramId, cultureProgramId)
                .isNull(ObeCultureProgramRequirement::getParentId);

        UpdateWrapper<ObeCultureProgram> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(ObeCultureProgram::getRequirementCount, obeCultureProgramRequirementService.count(queryWrapper))
                .eq(ObeCultureProgram::getId, cultureProgramId);
        this.update(updateWrapper);
    }

    @Override
    public void updateCourseCount(Long cultureProgramId) {
        QueryWrapper<ObeCultureProgramCourse> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ObeCultureProgramCourse::getCultureProgramId, cultureProgramId);

        UpdateWrapper<ObeCultureProgram> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(ObeCultureProgram::getCourseCount, obeCultureProgramCourseService.count(queryWrapper))
                .eq(ObeCultureProgram::getId, cultureProgramId);
        this.update(updateWrapper);
    }

    @Override
    public boolean saveDescription(ObeCultureProgramDescriptionParam obeCultureProgramDescriptionParam) {
        UpdateWrapper<ObeCultureProgram> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(ObeCultureProgram::getId, obeCultureProgramDescriptionParam.getId())
                .set(ObeCultureProgram::getDescription, obeCultureProgramDescriptionParam.getDescription());
        return this.update(updateWrapper);
    }

    @Override
    public Long copyByCultureProgramId(Long id) {
        ObeCultureProgram obeCultureProgram = this.getById(id);
        if (obeCultureProgram == null) {
            throw ExceptionResultEnum.ERROR.exception("培养方案不存在");
        }
        AtomicInteger i = new AtomicInteger(1);
        String name = obeCultureProgram.getName() + "副本" + i.getAndIncrement();
        while (this.getBySchoolIdAndName(obeCultureProgram.getSchoolId(), name) != null) {
            name = obeCultureProgram.getName() + "副本" + i.getAndIncrement();
        }
        obeCultureProgram.setId(SystemConstant.getDbUuid());
        obeCultureProgram.setName(name);
        this.save(obeCultureProgram);
        return obeCultureProgram.getId();
    }

    @Override
    public CultureProgramResult getByCultureProgramId(Long id) {
        return this.baseMapper.getByCultureProgramId(id);
    }
}
