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


import com.keao.edu.auth.api.client.SysUserFeignService;
import com.keao.edu.auth.api.entity.SysUser;
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.user.api.entity.ExamRoom;
import com.keao.edu.user.api.entity.ExamRoomStudentRelation;
import com.keao.edu.user.dao.ExamReviewDao;
import com.keao.edu.user.dao.ExamRoomDao;
import com.keao.edu.user.dao.SysUserDao;
import com.keao.edu.user.dto.ExamReviewDto;
import com.keao.edu.user.dto.ExamReviewRecordDto;
import com.keao.edu.user.entity.ExamReview;
import com.keao.edu.user.entity.ExaminationBasic;
import com.keao.edu.user.entity.Subject;
import com.keao.edu.user.enums.ExamRoomTeaherTypeEnum;
import com.keao.edu.user.enums.YesOrNoEnum;
import com.keao.edu.user.page.ExamReviewQueryInfo;
import com.keao.edu.user.page.ExamReviewRecordQueryInfo;
import com.keao.edu.user.service.ExamReviewService;
import com.keao.edu.user.service.ExamRoomStudentRelationService;
import com.keao.edu.util.collection.MapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ExamReviewServiceImpl extends BaseServiceImpl<Long, ExamReview> implements ExamReviewService {
	
	@Autowired
	private ExamReviewDao examReviewDao;
	@Autowired
	private ExamRoomDao examRoomDao;
	@Autowired
	private SysUserFeignService sysUserFeignService;
	@Autowired
	private ExamRoomStudentRelationService examRoomStudentRelationService;
	@Autowired
	private SysUserDao sysUserDao;

	@Override
	public BaseDAO<Long, ExamReview> getDAO() {
		return examReviewDao;
	}

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

//		List<Integer> nextLevelOrganIds = organizationService.getChildOrganIds(queryInfo.getOrganId(), true);
//		params.put("organIds", nextLevelOrganIds);

		List<ExamReviewDto> dataList = null;
		int count = examReviewDao.countExamResult(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = examReviewDao.findExamResult(params);
			List<Integer> teacherIds = dataList.stream().map(ExamReviewDto::getTeacherId).collect(Collectors.toList());
			List<Integer> studentIds = dataList.stream().map(ExamReviewDto::getStudentId).collect(Collectors.toList());
			List<Long> examIds = dataList.stream().map(ExamReviewDto::getExaminationBasicId).collect(Collectors.toList());
			List<Integer> subjectIds = dataList.stream().map(e->e.getExamRegistration().getSubjectId()).collect(Collectors.toList());
			Map<Integer, String> teacherIdNameMap = this.getMap("sys_user", "id_", "real_name_", teacherIds, Integer.class, String.class);
			Map<Integer, String> studentIdNameMap = this.getMap("sys_user", "id_", "real_name_", studentIds, Integer.class, String.class);
			Map<Integer, String> subjectIdNameMap = this.getMap("subject", "id_", "name_", subjectIds, Integer.class, String.class);
			Map<Long, String> examIdNameMap = this.getMap("examination_basic", "id_", "name_", examIds, Long.class, String.class);
			for (ExamReviewDto e : dataList) {
				e.setTeacher(new SysUser(e.getTeacherId(),teacherIdNameMap.get(e.getTeacherId())));
				e.getExamRegistration().setSubject(new Subject(e.getExamRegistration().getSubjectId(), subjectIdNameMap.get(e.getExamRegistration().getSubjectId())));
				e.setStudentInfo(new SysUser(e.getStudentId(), studentIdNameMap.get(e.getStudentId())));
				e.setExaminationBasic(new ExaminationBasic(e.getExaminationBasicId(), examIdNameMap.get(e.getExaminationBasicId())));
			}
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public PageInfo<ExamReviewRecordDto> queryExamReviewRecordList(ExamReviewRecordQueryInfo queryInfo) {
		PageInfo<ExamReviewRecordDto> pageInfo = new PageInfo<>(queryInfo.getPage(), queryInfo.getRows());
		Map<String, Object> params = new HashMap<String, Object>();
		MapUtil.populateMap(params, queryInfo);
		List<ExamReviewRecordDto> dataList = null;
		int count = examReviewDao.countExamReviewRecordList(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = examReviewDao.queryExamReviewRecordList(params);
			List<Integer> collect = dataList.stream().map(e -> e.getStudentId()).collect(Collectors.toList());
			Map<Integer, String> realNames = getMap("sys_user", "id_", "real_name_", collect,Integer.class,String.class);
			dataList.forEach(e->{
				e.setRealName(realNames.get(e.getStudentId()));
			});
			pageInfo.setRows(dataList);
		}
		return pageInfo;
	}

	@Override
	@Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE)
	public void add(ExamReview examReview) {
		SysUser sysUser = sysUserFeignService.queryUserInfo();
		sysUserDao.lockUser(sysUser.getId());
		Long examRegistrationId = examReview.getExamRegistrationId();
		ExamReview byRegistrationId = examReviewDao.findByRegistrationId(examRegistrationId,sysUser.getId());
		if(byRegistrationId != null){
			throw new BizException("评审失败：请勿重复操作");
		}
		ExamRoomStudentRelation examRoomStudentRelation = examRoomStudentRelationService.getExamRoomStudentRelation(examRegistrationId);
		if(examRoomStudentRelation.getSignInTime() == null){
			throw new BizException("评审失败：学员未考试");
		}
		ExamRoom examRoom = examRoomDao.get(examRoomStudentRelation.getExamRoomId());
		if(examRoom.getMainTeacherUserId().equals(sysUser.getId())){
			examReview.setTeacherType(ExamRoomTeaherTypeEnum.MAIN);
		}else {
			examReview.setTeacherType(ExamRoomTeaherTypeEnum.ASSISTANT);
		}
		examReview.setExaminationBasicId(examRoomStudentRelation.getExaminationBasicId());
		examReview.setTeacherId(sysUser.getId());
		examReview.setStudentId(examRoomStudentRelation.getStudentId());
		examReview.setExamRoomId(examRoomStudentRelation.getExamRoomId());
		examReview.setTenantId(examRoomStudentRelation.getTenantId());
		if(sysUser.getId().equals(examRoom.getMainTeacherUserId())){
			examReview.setTeacherType(ExamRoomTeaherTypeEnum.MAIN);
		}else{
			examReview.setTeacherType(ExamRoomTeaherTypeEnum.ASSISTANT);
		}
		examReviewDao.insert(examReview);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int update(ExamReview examReview) {
		if(Objects.isNull(examReview.getId())){
			throw new BizException("考试结果不存在");
		}
		ExamReview existExamReview = examReviewDao.get(examReview.getId());
		if(Objects.isNull(existExamReview)){
			throw new BizException("考试结果不存在");
		}
		if(YesOrNoEnum.YES.equals(existExamReview.getEnableEdit())){
			throw new BizException("编辑已锁定");
		}
		return super.update(examReview);
	}
}
