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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.ExamDetailCourseDto;
import com.qmth.distributed.print.business.bean.dto.SyncExamTaskDto;
import com.qmth.distributed.print.business.entity.ExamCard;
import com.qmth.distributed.print.business.entity.ExamDetailCourse;
import com.qmth.distributed.print.business.entity.ExamTaskDetail;
import com.qmth.distributed.print.business.enums.*;
import com.qmth.distributed.print.business.mapper.ExamDetailCourseMapper;
import com.qmth.distributed.print.business.service.ExamCardService;
import com.qmth.distributed.print.business.service.ExamDetailCourseService;
import com.qmth.distributed.print.business.service.ExamTaskDetailService;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicCourse;
import com.qmth.teachcloud.common.entity.SysOrg;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.CardCreateMethodEnum;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.service.SysOrgService;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 考务数据（考场关联科目） 服务实现类
 * </p>
 *
 * @author xf
 * @since 2021-03-23
 */
@Service
public class ExamDetailCourseServiceImpl extends ServiceImpl<ExamDetailCourseMapper, ExamDetailCourse> implements ExamDetailCourseService {

    @Resource
    private ExamTaskDetailService examTaskDetailService;

    @Resource
    private ExamCardService examCardService;

    @Resource
    private SysOrgService sysOrgService;

    @Override
    public List<Map<String, Object>> listByExamDetailId(Long examDetailId) {
        return this.baseMapper.listByExamDetailId(examDetailId, ExamDetailStatusEnum.FINISH.name());
    }

    @Override
    public void updatePaperNumber(List<Long> examDetailCourseIds, String paperNumber, String relatePaperType) {
        UpdateWrapper<ExamDetailCourse> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(ExamDetailCourse::getPaperNumber, paperNumber)
                .set(ExamDetailCourse::getPaperType, relatePaperType)
                .in(ExamDetailCourse::getId, examDetailCourseIds);
        this.update(updateWrapper);
    }

    @Override
    public List<ExamDetailCourse> listByExamDetailIdAndStatus(Long examDetailId) {
        return this.baseMapper.listByExamDetailIdAndStatus(examDetailId, ExamStatusEnum.SUBMIT.name());
    }

    @Override
    public List<BasicCourse> listCoursesByPrintPlanId(String param, List<Long> printPlanIdList) {
        return this.baseMapper.listCoursesByPrintPlanId(SystemConstant.translateSpecificSign(param), printPlanIdList);
    }

    @Override
    public List<String> listPaperNumberByPrintPlanId(String param, List<Long> printPlanIdList, Set<Long> orgIds) {
        return this.baseMapper.listPaperNumberByPrintPlanId(SystemConstant.translateSpecificSign(param), printPlanIdList, orgIds);
    }

    @Override
    public List<ExamDetailCourse> listByPrintPlanIdAndCourseCodeAndPaperNumber(Long schoolId, Long printPlanId, String courseCode, String paperNumber) {
        return this.baseMapper.listByPrintPlanIdAndCourseCodeAndPaperNumber(schoolId, printPlanId, courseCode, paperNumber);
    }

    @Override
    public List<ExamDetailCourse> listByCourseCodeAndPaperNumber(Long schoolId, Long examId, String courseCode, String paperNumber) {
        return this.baseMapper.listByAndCourseCodeAndPaperNumber(schoolId, examId, courseCode, paperNumber);
    }

    @Override
    public IPage<SyncExamTaskDto> listSyncCourseByPrintPlanId(Long semesterId, Long examId, Long orgId, SyncCardTypeEnum cardType, ExamTaskSyncStatusEnum syncStatus, String courseCode, String paperNumber, Long startTime, Long endTime, Integer pageNumber, Integer pageSize) {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        Page<SyncExamTaskDto> ipage = new Page<>(pageNumber, pageSize);
        // 顶级机构
        SysOrg rootOrg = sysOrgService.findRootOrg(sysUser.getSchoolId());
        // 查询用户所在机构及以下机构
        Set<Long> orgIds = sysOrgService.findDeepOrgIdListByUserId(sysUser.getId());
        IPage<SyncExamTaskDto> examTaskDtos = this.baseMapper.listSyncCourseByPrintPlanId(ipage, semesterId, examId, orgIds, cardType, syncStatus, courseCode, paperNumber, startTime, endTime);
        for (SyncExamTaskDto examTaskDto : examTaskDtos.getRecords()) {
            String paperType = examTaskDto.getPaperType();
            List<String> paperTypes = Arrays.asList(paperType.split(","));
            ExamTaskDetail examTaskDetail = examTaskDetailService.getByExamTaskId(Long.valueOf(examTaskDto.getExamTaskId()));
            List<JSONObject> paperAttachments = JSON.parseArray(examTaskDetail.getPaperAttachmentIds(), JSONObject.class);
            List<Long> cardIds = paperAttachments.stream().filter(m -> paperTypes.contains(m.getString("name"))).map(m -> m.getLong("cardId")).collect(Collectors.toList());
            QueryWrapper<ExamCard> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(ExamCard::getId, cardIds);

            List<ExamCard> cardList = examCardService.list(queryWrapper);
            Set<String> stringSet = new HashSet<>();
            for (ExamCard examCard : cardList) {
                if (examCard.getType().equals(CardTypeEnum.GENERIC) && examCard.getCreateMethod().equals(CardCreateMethodEnum.UPLOAD)) {
                    stringSet.add(SyncCardTypeEnum.GENERIC.getDesc());
                } else {
                    stringSet.add(SyncCardTypeEnum.CUSTOM.getDesc());
                }
            }
            if (stringSet.size() > 0) {
                examTaskDto.setSyncCardType(String.join(",", stringSet));
            }

            List<SysOrg> sysOrgList = sysOrgService.findByConnectByParentId(Long.valueOf(examTaskDto.getTeachingRoomId()), false, false);
            if(sysOrgList.isEmpty()){
                throw ExceptionResultEnum.ERROR.exception(String.format("未找到课程[%s（%s）]所属机构及上级机构", examTaskDto.getCourseName(), examTaskDto.getCourseCode()));
            }
            Optional<SysOrg> optionalSysOrg = sysOrgList.stream().filter(m->rootOrg.getId().equals(m.getParentId())).findFirst();
            if(optionalSysOrg.isPresent()){
                SysOrg collegeOrg = optionalSysOrg.get();
                examTaskDto.setCollegeId(String.valueOf(collegeOrg.getId()));
                examTaskDto.setCollegeCode(collegeOrg.getCode());
                examTaskDto.setCollegeName(collegeOrg.getName());
            } else {
                examTaskDto.setCollegeId("-");
                examTaskDto.setCollegeCode("-");
                examTaskDto.setCollegeName("-");
            }
        }
        return examTaskDtos;
    }

    @Override
    public List<ExamDetailCourseDto> listByPrintPlanIdAndExamTaskId(List<Long> printPlanIds, Long examTaskId) {
        return this.baseMapper.listByPrintPlanIdAndExamTaskId(printPlanIds, examTaskId);
    }
}
