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

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.distributed.print.business.bean.dto.obe.CourseRequirementMatrixDto;
import com.qmth.distributed.print.business.bean.dto.obe.MatrixRequirementDto;
import com.qmth.distributed.print.business.bean.dto.obe.MatrixSubRequirementDto;
import com.qmth.distributed.print.business.entity.ObeCourseRequirementMatrix;
import com.qmth.distributed.print.business.entity.ObeCultureProgramCourse;
import com.qmth.distributed.print.business.entity.ObeCultureProgramRequirement;
import com.qmth.distributed.print.business.entity.TeachCourse;
import com.qmth.distributed.print.business.mapper.ObeCourseRequirementMatrixMapper;
import com.qmth.distributed.print.business.service.ObeCourseRequirementMatrixService;
import com.qmth.distributed.print.business.service.ObeCultureProgramCourseService;
import com.qmth.distributed.print.business.service.ObeCultureProgramRequirementService;
import com.qmth.distributed.print.business.service.TeachCourseService;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicCourse;
import com.qmth.teachcloud.common.entity.SysPrivilege;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.service.BasicCourseService;
import com.qmth.teachcloud.common.service.SysPrivilegeService;
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 org.springframework.util.LinkedMultiValueMap;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 培养方案毕业要求支撑矩阵 服务实现类
 * </p>
 *
 * @author xf
 * @since 2024-06-05
 */
@Service
public class ObeCourseRequirementMatrixServiceImpl extends ServiceImpl<ObeCourseRequirementMatrixMapper, ObeCourseRequirementMatrix> implements ObeCourseRequirementMatrixService {

    @Resource
    private SysPrivilegeService sysPrivilegeService;
    @Resource
    private BasicCourseService basicCourseService;
    @Resource
    private TeachCourseService teachCourseService;
    @Resource
    private ObeCultureProgramCourseService obeCultureProgramCourseService;
    @Resource
    private ObeCultureProgramRequirementService obeCultureProgramRequirementService;

    @Override
    public List<CourseRequirementMatrixDto> getMatrix(Long cultureProgramId) {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        List<CourseRequirementMatrixDto> tpMatrixList = this.baseMapper.listMatrix(cultureProgramId, null);
        List<CourseRequirementMatrixDto> matrixDtoList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(tpMatrixList)) {
            List<SysPrivilege> sysPrivileges = sysPrivilegeService.getClientUrlByUserId(sysUser.getId());
            boolean canEditCourse = sysPrivileges.stream().filter(m -> m.getId() == 2056L && "canEditCourse".equals(m.getUrl())).count() > 0;
            List<String> codeList = new ArrayList<>();
            if (!canEditCourse) {
                List<TeachCourse> teachCourseList = teachCourseService.list(new QueryWrapper<TeachCourse>().lambda().eq(TeachCourse::getUserId, sysUser.getId()));
                if (CollectionUtils.isNotEmpty(teachCourseList)) {
                    codeList = teachCourseList.stream().map(TeachCourse::getCourseCode).distinct().collect(Collectors.toList());
                }
            }

            LinkedMultiValueMap<Long, CourseRequirementMatrixDto> courseMap = new LinkedMultiValueMap<>();
            for (CourseRequirementMatrixDto tpMatrix : tpMatrixList) {
                courseMap.add(tpMatrix.getObeCourseId(), tpMatrix);
            }
            List<String> finalCodeList = codeList;
            courseMap.entrySet().stream().forEach(entry -> {
                ObeCultureProgramCourse obeCultureProgramCourse = obeCultureProgramCourseService.getById(entry.getKey());
                BasicCourse basicCourse = basicCourseService.getById(obeCultureProgramCourse.getCourseId());
                CourseRequirementMatrixDto matrixDto = new CourseRequirementMatrixDto();
                matrixDto.setCourseCode(basicCourse.getCode());
                matrixDto.setCourseName(basicCourse.getName());
                matrixDto.setCanEdit(canEditCourse || finalCodeList.contains(basicCourse.getCode()));
                List<MatrixRequirementDto> matrixRequirementDtoList = new ArrayList<>();
                LinkedMultiValueMap<Long, CourseRequirementMatrixDto> requirementMap = new LinkedMultiValueMap<>();
                for (CourseRequirementMatrixDto tpMatrix : entry.getValue()) {
                    requirementMap.add(tpMatrix.getObeRequirementId(), tpMatrix);
                }
                requirementMap.entrySet().stream().forEach(requirementEntry -> {
                    ObeCultureProgramRequirement tpRequirement = obeCultureProgramRequirementService.getById(requirementEntry.getKey());
                    MatrixRequirementDto matrixRequirementDto = new MatrixRequirementDto();
                    matrixRequirementDto.setName(tpRequirement.getName());
                    matrixRequirementDto.setContent(tpRequirement.getContent());
                    matrixRequirementDto.setExpectValue(tpRequirement.getExpectValue());
                    List<CourseRequirementMatrixDto> requirementList = requirementEntry.getValue();
                    // 排序，解决字符串1和10排序问题
                    if (requirementList.size() > 1) {
                        requirementList.sort(Comparator.comparingInt(o -> o.getSubRequirementSortNum()));
                    }
                    List<MatrixSubRequirementDto> matrixSubRequirementDtoList = requirementList.stream().map(tpMatrix -> {
                        MatrixSubRequirementDto matrixSubRequirementDto = new MatrixSubRequirementDto();
                        matrixSubRequirementDto.setId(tpMatrix.getId());
                        matrixSubRequirementDto.setName(tpMatrix.getRequirementSortNum() + "-" + tpMatrix.getSubRequirementSortNum());
                        matrixSubRequirementDto.setScale(tpMatrix.getScale());
                        matrixSubRequirementDto.setContent(tpMatrix.getRequirementContent());
                        return matrixSubRequirementDto;
                    }).collect(Collectors.toList());
                    matrixRequirementDto.setSubRequirements(matrixSubRequirementDtoList);
                    matrixRequirementDtoList.add(matrixRequirementDto);
                });
                matrixDto.setRequirements(matrixRequirementDtoList);
                matrixDtoList.add(matrixDto);
            });
        }
        return matrixDtoList;
    }

    @Transactional
    @Override
    public boolean saveMatrix(List<ObeCourseRequirementMatrix> obeCourseRequirementMatrices) {
        for (ObeCourseRequirementMatrix tpMatrix : obeCourseRequirementMatrices) {
            UpdateWrapper<ObeCourseRequirementMatrix> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().set(ObeCourseRequirementMatrix::getScale, tpMatrix.getScale())
                    .eq(ObeCourseRequirementMatrix::getId, tpMatrix.getId());
            this.update(updateWrapper);
        }
        return true;
    }

    @Override
    public void updateMatrix(Long cultureProgramId, List<ObeCultureProgramRequirement> requirementList, List<ObeCultureProgramCourse> courseList) {
        if (CollectionUtils.isEmpty(requirementList) && CollectionUtils.isEmpty(courseList)) {
            throw ExceptionResultEnum.ERROR.exception("生成课程支撑毕业要求达成矩阵数据有误");
        }
        if (CollectionUtils.isEmpty(requirementList)) {
            requirementList = obeCultureProgramRequirementService.listRequirement(cultureProgramId);
        }
        if (CollectionUtils.isEmpty(courseList)) {
            courseList = obeCultureProgramCourseService.listCourse(cultureProgramId);
        }

        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        List<ObeCourseRequirementMatrix> obeCourseRequirementMatrices = new ArrayList<>();
        for (ObeCultureProgramRequirement obeCultureProgramRequirement : requirementList) {
            for (ObeCultureProgramRequirement cultureProgramRequirement : obeCultureProgramRequirement.getSubRequirementList()) {
                for (ObeCultureProgramCourse obeCultureProgramCourse : courseList) {
                    ObeCourseRequirementMatrix obeCourseRequirementMatrix = new ObeCourseRequirementMatrix(obeCultureProgramRequirement.getCultureProgramId(), obeCultureProgramCourse.getId(), cultureProgramRequirement.getParentId(), cultureProgramRequirement.getId());
                    obeCourseRequirementMatrix.insertInfo(sysUser.getId());
                    obeCourseRequirementMatrices.add(obeCourseRequirementMatrix);
                }
            }
        }
        if (CollectionUtils.isNotEmpty(obeCourseRequirementMatrices)) {
            this.saveBatch(obeCourseRequirementMatrices);
        }
    }

    @Override
    public void removeMatrixByCondition(ObeCourseRequirementMatrix obeCourseRequirementMatrix) {
        UpdateWrapper<ObeCourseRequirementMatrix> updateWrapper = new UpdateWrapper<>();
        LambdaUpdateWrapper<ObeCourseRequirementMatrix> lambda = updateWrapper.lambda();
        if (obeCourseRequirementMatrix.getCultureProgramId() != null) {
            lambda.eq(ObeCourseRequirementMatrix::getCultureProgramId, obeCourseRequirementMatrix.getCultureProgramId());
        }
        if (obeCourseRequirementMatrix.getObeCourseId() != null) {
            lambda.eq(ObeCourseRequirementMatrix::getObeCourseId, obeCourseRequirementMatrix.getObeCourseId());
        }
        if (obeCourseRequirementMatrix.getObeRequirementId() != null) {
            lambda.eq(ObeCourseRequirementMatrix::getObeRequirementId, obeCourseRequirementMatrix.getObeRequirementId());
        }
        if (obeCourseRequirementMatrix.getObeSubRequirementId() != null) {
            lambda.eq(ObeCourseRequirementMatrix::getObeSubRequirementId, obeCourseRequirementMatrix.getObeSubRequirementId());
        }
        this.remove(updateWrapper);
    }

    @Override
    public void copyByCultureProgramId(Long id, Long obeCultureProgramNewId, Map<Long, Long> requirementIdMap, Map<Long, Long> courseIdMap) {
        List<ObeCourseRequirementMatrix> obeCourseRequirementMatrixList = this.list(new QueryWrapper<ObeCourseRequirementMatrix>().lambda().eq(ObeCourseRequirementMatrix::getCultureProgramId, id));
        for (ObeCourseRequirementMatrix obeCourseRequirementMatrix : obeCourseRequirementMatrixList) {
            obeCourseRequirementMatrix.setId(SystemConstant.getDbUuid());
            obeCourseRequirementMatrix.setCultureProgramId(obeCultureProgramNewId);
            obeCourseRequirementMatrix.setObeCourseId(courseIdMap.get(obeCourseRequirementMatrix.getObeCourseId()));
            obeCourseRequirementMatrix.setObeRequirementId(requirementIdMap.get(obeCourseRequirementMatrix.getObeRequirementId()));
            obeCourseRequirementMatrix.setObeSubRequirementId(requirementIdMap.get(obeCourseRequirementMatrix.getObeSubRequirementId()));
        }
        if (CollectionUtils.isNotEmpty(obeCourseRequirementMatrixList)) {
            this.saveBatch(obeCourseRequirementMatrixList);
        }
    }
}
