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.dto.BasicPrintConfigDto;
import com.qmth.distributed.print.business.entity.BasicTemplateOrg;
import com.qmth.distributed.print.business.entity.ExamTask;
import com.qmth.distributed.print.business.enums.TemplateTypeEnum;
import com.qmth.distributed.print.business.mapper.BasicPrintConfigMapper;
import com.qmth.distributed.print.business.service.BasicExamService;
import com.qmth.distributed.print.business.service.BasicPrintConfigService;
import com.qmth.distributed.print.business.service.BasicTemplateOrgService;
import com.qmth.distributed.print.business.service.ExamTaskService;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicExam;
import com.qmth.teachcloud.common.entity.BasicPrintConfig;
import com.qmth.teachcloud.common.entity.SysOrg;
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.SysOrgService;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 印品配置 服务实现类
 * </p>
 *
 * @author xf
 * @since 2022-02-10
 */
@Service
public class BasicPrintConfigServiceImpl extends ServiceImpl<BasicPrintConfigMapper, BasicPrintConfig> implements BasicPrintConfigService {

    @Resource
    private BasicTemplateOrgService basicTemplateOrgService;

    @Resource
    private ExamTaskService examTaskService;

    @Resource
    private BasicCourseService basicCourseService;

    @Autowired
    private BasicExamService basicExamService;

    @Autowired
    private SysOrgService sysOrgService;

    @Override
    public IPage<BasicPrintConfigDto> listPage(Long examId, Boolean enable, Long createStartTime, Long createEndTime, Integer pageNumber, Integer pageSize) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        Page<BasicPrintConfigDto> page = new Page<>(pageNumber, pageSize);
        IPage<BasicPrintConfigDto> printConfigDtoIPage = this.baseMapper.listPage(page, schoolId, examId, enable, createStartTime, createEndTime);
        if (printConfigDtoIPage.getRecords().size() > 0) {
            printConfigDtoIPage.getRecords().forEach(m -> {
                //查询适用学院
                List<SysOrg> sysOrgs = basicTemplateOrgService.listByTypeAndTemplateId(TemplateTypeEnum.PRINT_CONFIG.name(), Long.valueOf(m.getId()));
                if (sysOrgs != null && sysOrgs.size() > 0) {
                    String orgNames = sysOrgs.stream().map(SysOrg::getName).collect(Collectors.joining(","));
                    m.setOrgNames(orgNames);
                }
                m.setOrgs(sysOrgs);
            });
        }
        return printConfigDtoIPage;
    }

    @Override
    public boolean enable(Long id, Boolean enable) {
        UpdateWrapper<BasicPrintConfig> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(BasicPrintConfig::getEnable, enable).eq(BasicPrintConfig::getId, id);
        return this.update(updateWrapper);
    }

    @Transactional
    @Override
    public boolean savePrintConfig(BasicPrintConfig basicPrintConfig) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        basicPrintConfig.setSchoolId(schoolId);
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();

        boolean isSuccess;

        // 新增
        if (Objects.isNull(basicPrintConfig.getId())) {
            QueryWrapper<BasicPrintConfig> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(BasicPrintConfig::getSchoolId, schoolId).eq(BasicPrintConfig::getExamId, basicPrintConfig.getExamId());
            List<BasicPrintConfig> basicPrintConfigs = this.list(queryWrapper);
            // 同一个考试下，一个学院只能对应一个印品配置方案
            Long[] orgIds = basicPrintConfig.getOrgIds();
            if (basicPrintConfigs != null && basicPrintConfigs.size() > 0) {
                List<Long> printConfigIds = basicPrintConfigs.stream().map(BasicPrintConfig::getId).collect(Collectors.toList());
                QueryWrapper<BasicTemplateOrg> basicTemplateOrgQueryWrapper = new QueryWrapper<>();
                basicTemplateOrgQueryWrapper.lambda().in(BasicTemplateOrg::getRuleId, printConfigIds).eq(BasicTemplateOrg::getType, TemplateTypeEnum.PRINT_CONFIG)
                        .in(BasicTemplateOrg::getOrgId, orgIds);
                List<BasicTemplateOrg> basicTemplateOrgList = basicTemplateOrgService.list(basicTemplateOrgQueryWrapper);
                if (basicTemplateOrgList != null && basicTemplateOrgList.size() > 0) {
                    throw ExceptionResultEnum.ERROR.exception("有" + basicTemplateOrgList.size() + "个机构已经设置了印品，不能重复设置");
                }
            }

            basicPrintConfig.setId(SystemConstant.getDbUuid());
            basicPrintConfig.setCreateId(sysUser.getId());
            basicPrintConfig.setCreateTime(System.currentTimeMillis());
            isSuccess = this.save(basicPrintConfig);
        }
        // 修改
        else {
            QueryWrapper<BasicPrintConfig> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(BasicPrintConfig::getSchoolId, schoolId)
                    .eq(BasicPrintConfig::getExamId, basicPrintConfig.getExamId())
                    .ne(BasicPrintConfig::getId, basicPrintConfig.getId());
            List<BasicPrintConfig> basicPrintConfigs = this.list(queryWrapper);
            // 一个学院只能对应一个印品配置方案
            Long[] orgIds = basicPrintConfig.getOrgIds();
            if (basicPrintConfigs != null && basicPrintConfigs.size() > 0) {
                List<Long> printConfigIds = basicPrintConfigs.stream().map(BasicPrintConfig::getId).collect(Collectors.toList());
                QueryWrapper<BasicTemplateOrg> basicTemplateOrgQueryWrapper = new QueryWrapper<>();
                basicTemplateOrgQueryWrapper.lambda().in(BasicTemplateOrg::getRuleId, printConfigIds)
                        .eq(BasicTemplateOrg::getType, TemplateTypeEnum.PRINT_CONFIG)
                        .in(BasicTemplateOrg::getOrgId, orgIds);
                List<BasicTemplateOrg> basicTemplateOrgList = basicTemplateOrgService.list(basicTemplateOrgQueryWrapper);
                if (basicTemplateOrgList != null && basicTemplateOrgList.size() > 0) {
                    throw ExceptionResultEnum.ERROR.exception("有" + basicTemplateOrgList.size() + "个机构已经设置了印品，不能重复设置");
                }
            }

            basicPrintConfig.setUpdateId(sysUser.getId());
            basicPrintConfig.setUpdateTime(System.currentTimeMillis());

            //删除权限
            basicTemplateOrgService.removeByRuleId(basicPrintConfig.getId());
            isSuccess = this.updateById(basicPrintConfig);

        }

        // 新增权限
        basicTemplateOrgService.saveBatch(schoolId, TemplateTypeEnum.PRINT_CONFIG, basicPrintConfig.getId(), basicPrintConfig.getOrgIds(), basicPrintConfig.getCreateId());

        return isSuccess;
    }

    @Override
    public BasicPrintConfig getByExamIdAndCourseCode(Long examId, String courseCode) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        // 查询科目所属教研室
        Long orgId = basicCourseService.getOrgIdBySchoolIdAndCourseCode(schoolId, courseCode);
        if (orgId == null) {
            throw ExceptionResultEnum.ERROR.exception("未找到课程所属机构");
        }
        BasicExam basicExam = basicExamService.getById(examId);
        SysOrg sysOrg = sysOrgService.getById(orgId);

        List<BasicPrintConfig> basicPrintConfigs = this.baseMapper.listBySchoolIdAndExamIdAndOrgId(schoolId, examId, orgId, TemplateTypeEnum.PRINT_CONFIG.name());
        if (basicPrintConfigs == null || basicPrintConfigs.size() == 0) {
            throw ExceptionResultEnum.ERROR.exception("未找到课程[" + basicCourseService.findByCourseCode(courseCode, schoolId).getName() + "]所属教研室[" + sysOrg.getName() + "]的印品配置");
        }
        if (basicPrintConfigs.size() != 1) {
            throw ExceptionResultEnum.ERROR.exception("考试[" + basicExam.getName() + "],教研室[" + sysOrg.getName() + "]查询出多个印品配置");
        }
        BasicPrintConfig printConfig = basicPrintConfigs.get(0);
        if (!printConfig.getEnable()) {
            throw ExceptionResultEnum.ERROR.exception("考试[" + basicExam.getName() + "],教研室[" + sysOrg.getName() + "]印品配置已禁用，请先开启");
        }
        return printConfig;
    }

    @Override
    public BasicPrintConfig getByCourseCodeAndPaperNumber(String courseCode, String paperNumber) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());

        // 查询科目所属教研室
        Long orgId = basicCourseService.getOrgIdBySchoolIdAndCourseCode(schoolId, courseCode);
        if (orgId == null) {
            throw ExceptionResultEnum.ERROR.exception("未找到课程所属机构");
        }
        ExamTask examTask = examTaskService.getByCourseCodeAndPaperNumber(schoolId, courseCode, paperNumber);
        if (examTask == null) {
            throw ExceptionResultEnum.ERROR.exception("命题任务不存在");
        }
        return getByExamIdAndOrgId(examTask.getExamId(), orgId);
    }

    @Override
    public BasicPrintConfig getByExamIdAndOrgId(Long examId, Long orgId) {
        BasicExam basicExam = basicExamService.getById(examId);
        SysOrg sysOrg = sysOrgService.getById(orgId);
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        List<BasicPrintConfig> basicPrintConfigs = this.baseMapper.listBySchoolIdAndExamIdAndOrgId(schoolId, examId, orgId, TemplateTypeEnum.PRINT_CONFIG.name());
        if (basicPrintConfigs == null || basicPrintConfigs.size() == 0) {
            throw ExceptionResultEnum.ERROR.exception("考试[" + basicExam.getName() + "],教研室[" + sysOrg.getName() + "]未设置印品");
        }
        if (basicPrintConfigs.size() != 1) {
            throw ExceptionResultEnum.ERROR.exception("考试[" + basicExam.getName() + "],教研室[" + sysOrg.getName() + "]查询出多个印品配置");
        }

        BasicPrintConfig printConfig = basicPrintConfigs.get(0);
        if (!printConfig.getEnable()) {
            throw ExceptionResultEnum.ERROR.exception("考试[" + basicExam.getName() + "],教研室[" + sysOrg.getName() + "]印品配置已禁用，请先开启");
        }
        return printConfig;
    }

    @Override
    public List<String> listOrgIdsByExamId(Long id, Long examId) {
        QueryWrapper<BasicPrintConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(BasicPrintConfig::getExamId, examId);
        if (id != null) {
            queryWrapper.lambda().ne(BasicPrintConfig::getId, id);
        }
        List<BasicPrintConfig> basicPrintConfigs = this.list(queryWrapper);
        List<String> orgIds = new ArrayList<>();
        for (BasicPrintConfig basicPrintConfig : basicPrintConfigs) {
            List<SysOrg> sysOrgList = basicTemplateOrgService.listByTypeAndTemplateId(TemplateTypeEnum.PRINT_CONFIG.name(), basicPrintConfig.getId());
            for (SysOrg sysOrg : sysOrgList) {
                orgIds.add(String.valueOf(sysOrg.getId()));
            }
        }
        return orgIds;
    }

    @Transactional
    @Override
    public boolean delete(Long id) {
        this.removeById(id);
        // 删除适用学院
        basicTemplateOrgService.removeByRuleId(id);
        return true;
    }
}
