package com.keao.edu.user.service.impl;

import com.keao.edu.common.dal.BaseDAO;
import com.keao.edu.common.exception.BizException;
import com.keao.edu.common.page.PageInfo;
import com.keao.edu.common.service.impl.BaseServiceImpl;
import com.keao.edu.common.tenant.TenantContextHolder;
import com.keao.edu.user.dao.ExamOrganizationRelationDao;
import com.keao.edu.user.dao.ExaminationBasicDao;
import com.keao.edu.user.dto.ExaminationBasicDto;
import com.keao.edu.user.entity.ExamOrganizationRelation;
import com.keao.edu.user.entity.ExaminationBasic;
import com.keao.edu.user.api.enums.ExamModeEnum;
import com.keao.edu.user.enums.ExamStatusEnum;
import com.keao.edu.user.page.ExaminationQueryInfo;
import com.keao.edu.user.service.ExaminationBasicService;
import com.keao.edu.util.collection.MapUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ExaminationBasicServiceImpl extends BaseServiceImpl<Long, ExaminationBasic> implements ExaminationBasicService{

	@Autowired
	private ExaminationBasicDao examinationBasicDao;
	@Autowired
	private ExamOrganizationRelationDao examOrganizationRelationDao;

	@Override
	public BaseDAO<Long, ExaminationBasic> getDAO() {
		return examinationBasicDao;
	}

	@Override
	public ExaminationBasic addExaminationBasic(ExaminationBasic examinationBasic) {
		if(StringUtils.isBlank(examinationBasic.getName())){
			throw new BizException("请填写项目名称");
		}
		if(Objects.isNull(examinationBasic.getExamMode())){
			throw new BizException("请选择考试类型");
		}
		if(ExamModeEnum.OFFLINE.equals(examinationBasic.getExamMode())&&Objects.nonNull(examinationBasic.getExamLocationIdList())){
			throw new BizException("请指定考试地点");
		}
		if(Objects.isNull(examinationBasic.getEnrollStartTime())||Objects.isNull(examinationBasic.getEnrollEndTime())){
			throw new BizException("请指定考试开始与结束时间");
		}
		examinationBasic.setStatus(ExamStatusEnum.SETTING);
		examinationBasic.setTenantId(TenantContextHolder.getTenantId().toString());
		examinationBasicDao.insert(examinationBasic);
		return examinationBasic;
	}

	@Override
	public void updateExamStatus() {
		List<ExaminationBasic> needUpdateStatusExams = examinationBasicDao.getNeedUpdateStatusExams();
		if(CollectionUtils.isEmpty(needUpdateStatusExams)){
			return;
		}
		Date now=new Date();
		for (ExaminationBasic needUpdateStatusExam : needUpdateStatusExams) {
			if(now.compareTo(needUpdateStatusExam.getEnrollStartTime())>=0){
				needUpdateStatusExam.setStatus(ExamStatusEnum.APPLYING);
			}
			if(now.compareTo(needUpdateStatusExam.getEnrollEndTime())>=0){
				needUpdateStatusExam.setStatus(ExamStatusEnum.APPLIED);
			}
			if(now.compareTo(needUpdateStatusExam.getExpectExamStartTime())>=0){
				needUpdateStatusExam.setStatus(ExamStatusEnum.EXAM_ING);
			}
		}
		examinationBasicDao.batchUpdate(needUpdateStatusExams);
	}

	@Override
	public PageInfo<ExaminationBasicDto> findExaminationBasics(ExaminationQueryInfo queryInfo) {
		PageInfo<ExaminationBasicDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<String, Object>();
		MapUtil.populateMap(params, queryInfo);

		List<ExaminationBasicDto> dataList = new ArrayList<>();
		int count = examinationBasicDao.countExaminationBasics(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = examinationBasicDao.findExaminationBasics(params);
			List<Integer> examIds = dataList.stream().map(ExaminationBasicDto::getId).collect(Collectors.toList());
			List<ExamOrganizationRelation> examOrgans = examOrganizationRelationDao.getWithExams(examIds);
			Map<Integer, List<ExamOrganizationRelation>> examOrgansMap = new HashMap<>();
			if(!CollectionUtils.isEmpty(examOrgans)){
				examOrgansMap = examOrgans.stream().collect(Collectors.groupingBy(ExamOrganizationRelation::getExaminationBasicId));
			}
			for (ExaminationBasicDto examinationBasicDto : dataList) {
				List<ExamOrganizationRelation> examOrganizationRelations = examOrgansMap.get(examinationBasicDto.getId());
				if(CollectionUtils.isEmpty(examOrganizationRelations)){
					continue;
				}
				long totalRegistrationStudentNum = examOrganizationRelations.stream().map(ExamOrganizationRelation::getTotalRegistrationStudentNum).count();
				long totalPaymentAmount = examOrganizationRelations.stream().map(ExamOrganizationRelation::getTotalPaymentAmount).count();
				examinationBasicDto.setTotalRegistrationStudentNum((int) totalRegistrationStudentNum);
				examinationBasicDto.setTotalPaymentAmount(new BigDecimal(totalPaymentAmount));
			}
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public ExaminationBasicDto getExaminationBasic(Integer examId) {
		if(Objects.isNull(examId)){
			throw new BizException("请指定考级项目");
		}
		ExaminationBasicDto examinationBasic = examinationBasicDao.getExaminationBasic(examId);
		if(Objects.isNull(examinationBasic)){
			throw new BizException("指定的考级项目不存在");
		}
		List<ExamOrganizationRelation> examOrganizationRelations = examOrganizationRelationDao.getWithExam(examId);
		if(!CollectionUtils.isEmpty(examOrganizationRelations)){
			long totalRegistrationStudentNum = examOrganizationRelations.stream().map(ExamOrganizationRelation::getTotalRegistrationStudentNum).count();
			long totalPaymentAmount = examOrganizationRelations.stream().map(ExamOrganizationRelation::getTotalPaymentAmount).count();
			examinationBasic.setTotalRegistrationStudentNum((int) totalRegistrationStudentNum);
			examinationBasic.setTotalPaymentAmount(new BigDecimal(totalPaymentAmount));
		}
		return examinationBasic;
	}

	@Override
	public void closeExam(Integer examId, String reason) {
		if(Objects.isNull(examId)){
			throw new BizException("请指定考级项目");
		}
		ExaminationBasic examinationBasic = examinationBasicDao.get(examId.longValue());
		if(Objects.isNull(examinationBasic)){
			throw new BizException("考级项目不存在");
		}
		if(StringUtils.isBlank(reason)){
			reason="后台手动关闭";
		}
		examinationBasic.setMemo(reason);
		examinationBasic.setStatus(ExamStatusEnum.CLOSE);
		examinationBasicDao.update(examinationBasic);
	}

    @Override
    public ExaminationBasic getInfo(Integer examId) {
		return examinationBasicDao.get(examId.longValue());
	}
}
