package com.ym.mec.biz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ym.mec.auth.api.client.SysUserFeignService;
import com.ym.mec.auth.api.entity.SysUser;
import com.ym.mec.auth.api.enums.YesOrNoEnum;
import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.dto.*;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.page.*;
import com.ym.mec.biz.service.ClassGroupService;
import com.ym.mec.biz.service.TeacherService;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.entity.ImGroupModel;
import com.ym.mec.common.entity.ImResult;
import com.ym.mec.common.entity.ImUserModel;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.PageInfo;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.im.ImFeignService;
import com.ym.mec.util.collection.MapUtil;
import com.ym.mec.util.idcard.IdcardValidator;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class TeacherServiceImpl extends BaseServiceImpl<Integer, Teacher>  implements TeacherService {

	@Autowired
	private TeacherDao teacherDao;
	@Autowired
	private SubjectDao subjectDao;
	@Autowired
	private ClassGroupDao classGroupDao;
	@Autowired
	private ClassGroupService classGroupService;
	@Autowired
	private MusicGroupDao musicGroupDao;
	@Autowired
	private DemoGroupDao demoGroupDao;
	@Autowired
	private OrganizationDao organizationDao;
	@Autowired
	private SchoolDao schoolDao;
	@Autowired
	private SysUserCashAccountDao sysUserCashAccountDao;
	@Autowired
	private StudentPaymentOrderDao studentPaymentOrderDao;
	@Autowired
	private SysUserFeignService sysUserFeignService;
	@Autowired
	private ImFeignService imFeignService;
	@Autowired
	private SysConfigDao configDao;


	@Override
	public BaseDAO<Integer, Teacher> getDAO() {
		return teacherDao;
	}

	@Override
	public Teacher findByCertificateNum(String certificateNum){
		return teacherDao.findByCertificateNum(certificateNum);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int add(Teacher teacher) throws Exception {
		SysUser user = sysUserFeignService.queryUserByMobile(teacher.getPhone());
		if(user != null && user.getId() != null){
			if(user.getUserType().contains("TEACHER")){
				throw new BizException("此手机号已被占用");
			}
			Integer id = user.getId();
			Teacher teacher1 = teacherDao.get(id);
			if(teacher1 == null || teacher1.getId() == null){
				teacher.setId(id);
				teacher.setDelFlag(YesOrNoEnum.NO);
				teacherDao.insert(teacher);
				teacher.setOrganId(null);
				teacher.setUserType(user.getUserType() + ",TEACHER");
				teacherDao.updateUser(teacher);
			}else {
				throw new BizException("用户已存在");
			}
			return id;
		}
		teacher.setUserType("TEACHER");
		teacher.setUsername(teacher.getRealName());
		teacherDao.addSysUser(teacher);
		//添加用户现金账户
		sysUserCashAccountDao.insert(new SysUserCashAccount(teacher.getId(),"CNY"));
		//添加用户电子签章账户
//		contractService.register(teacher.getId(), user.getRealName(), user.getIdCardNo(), user.getPhone());
		teacherDao.insert(teacher);
		ImResult imResult = imFeignService.register(new ImUserModel(teacher.getId().toString(), teacher.getUsername(), null));
		if(imResult != null){
			teacher.setImToken(imResult.getToken());
			teacherDao.updateUser(teacher);
		}
		return teacher.getId();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateTea(Teacher teacher) {
		Teacher teacher1 = teacherDao.get(teacher.getId());
		if(null==teacher1){
			throw new BizException("教师信息不存在");
		}
		if(StringUtils.isNotEmpty(teacher.getPhone())){
			SysUser sysUser = sysUserFeignService.queryUserByMobile(teacher.getPhone());
			if(sysUser != null && !sysUser.getId().equals(teacher.getId())){
				throw new BizException("手机号已存在");
			}
		}
		teacher.setUpdateTime(new Date());
		teacher.setTeacherOrganId(teacher.getOrganId());
		teacherDao.update(teacher);
		teacher.setOrganId(null);
		teacherDao.updateUser(teacher);
		imFeignService.update(new ImUserModel(teacher.getId().toString(),teacher.getRealName(),teacher.getAvatar()));
	}

	@Override
	public void deleteTeacher(Long userId) {
		SysUser sysUser=new SysUser();
		sysUser.setId(userId.intValue());
		sysUser.setDelFlag(YesOrNoEnum.YES);
		teacherDao.updateUser(sysUser);
	}

	@Override
	public List<ImGroupModel> queryTeacherGroups(Integer userId,String search) {
		//获取教师所在班级列表
		List<ImGroupModel> imGroupModels =  classGroupDao.queryTeacherGroups(userId,search);
		if(imGroupModels != null && imGroupModels.size() > 0){
//			Set<String> classGroupIds = imGroupModels.stream().map(e -> e.getId()).collect(Collectors.toSet());
			//获取班级老师总数map
//			Map<Integer, Integer> numsMap = JSONObject.parseObject(JSONObject.toJSONString(MapUtil.convertIntegerMap(classGroupDao.countTeacherNums(StringUtils.join(classGroupIds, ",")))),HashMap.class);

			imGroupModels.forEach(e -> {
//				Integer num = numsMap.get(Integer.parseInt(e.getId()));
				e.setCount(classGroupService.findGroupUsers(Integer.parseInt(e.getId())).size());
			});
		}
		return imGroupModels;
	}

	@Override
	public List<BasicUserDto> queryGroupStudents(Integer teacherId, String search) {
		List<ImGroupModel> musicGroups =  musicGroupDao.queryTeacherGroups(teacherId,search);
		List<BasicUserDto> teachers = new ArrayList<>();
		if(musicGroups != null && musicGroups.size() > 0){
			Set<String> musicGroupId = musicGroups.stream().map(ImGroupModel::getId).collect(Collectors.toSet());
			List<MusicGroup> musicGroupList = musicGroupDao.queryListByIds(StringUtils.join(musicGroupId, ","));
			Set<Integer> teacherIds = new HashSet<>();
			if(musicGroupList != null && musicGroupList.size() > 0){
				musicGroupList.forEach(e->{
					teacherIds.add(e.getTeamTeacherId());
					teacherIds.add(e.getEducationalTeacherId());
					teacherIds.add(e.getDirectorUserId());
				});
			}
			teacherIds.remove(teacherId);
			teacherIds.removeAll(Collections.singleton(null));
			if(teacherIds.size() > 0){
				teachers = teacherDao.queryMusicGroupStudents(StringUtils.join(teacherIds,","), search);
			}
		}
		List<BasicUserDto> userDtos = teacherDao.queryGroupStudents(teacherId, search);
		if(userDtos != null && userDtos.size() > 0){
			teachers.addAll(userDtos);
			Set<String> musicGroupIds = userDtos.stream().map(e -> e.getMusicGroupId()).collect(Collectors.toSet());
			if(musicGroupIds != null && musicGroupIds.size() > 0){
				Map<String, String> musicGroupNameMap = MapUtil.convertIntegerMap(musicGroupDao.queryMusicGroupNameMap(musicGroupIds));
				userDtos.forEach(e->{
					e.setMusicGroupName(musicGroupNameMap.get(e.getMusicGroupId()));
				});
			}
		}
		//获取课程关联的学生列表
		teachers.addAll(teacherDao.findCloseCourseStudentIds(teacherId, search));
		return teachers.stream().distinct().collect(Collectors.toList());
	}

    @Override
    public List<TeacherBasicDto> findTeachers(String organId) {
		List<Teacher> teacherList = teacherDao.findByFlowOrganRange(null);
		if(StringUtils.isNotEmpty(organId)){
			Set<String> list = new HashSet<>(Arrays.asList(organId.split(",")));
			teacherList = teacherList.stream().
					filter(teacher -> !Collections.disjoint(new ArrayList<>(Arrays.asList(teacher.getFlowOrganRange().split(","))),list)).collect(Collectors.toList());
		}
		List<Integer> userIds = teacherList.stream().map(e -> e.getId()).collect(Collectors.toList());
		if(userIds != null && userIds.size() > 0){
			return teacherDao.findTeachers(userIds);
		}
		return new ArrayList<>();
    }

	@Override
	public List<Teacher> findOrganTeacherBySubject(Integer subjectId) {
		return teacherDao.findOrganTeacherBySubject(subjectId);
	}

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

		List<TeacherCloseDto> dataList = null;
		int count = teacherDao.countCloses(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = teacherDao.queryCloses(params);
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public BigDecimal findTeacherNoPay(Integer teacherId) {
		return teacherDao.findTeacherNoPay(teacherId);
	}

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

		List<MusicGroupTeachersDto> dataList = null;
		int count = teacherDao.countMusicGroupTeachers(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = teacherDao.queryMusicGroupTeachers(params);
			//获取合奏班id列表
//			Set<Integer> classGroupIds = dataList.stream().map(e -> e.getClassGroupId()).collect(Collectors.toSet());
//			String classGroupIdStr = StringUtils.join(classGroupIds,",");
			//获取教师id列表
			Set<Integer> teacherIds = dataList.stream().map(e -> e.getTeacherId()).collect(Collectors.toSet());
//			String teacherIdStr = StringUtils.join(teacherIds,",");

			//根据教师编号和班级编号，获取老师签到次数
			Map<Integer,Integer> signNumMap =  JSONObject.parseObject(JSONObject.toJSONString(MapUtil.convertIntegerMap(teacherDao.findSignNum(StringUtils.join(teacherIds,","),queryInfo.getMusicGroupId()))),HashMap.class);
//			Map<Integer,Integer> signNumMap = JSONObject.parseObject(JSONObject.toJSONString(MapUtil.convertMybatisMap(signNum)),HashMap.class);

			//根据合奏班编号，获取子班级名称列表
//			List<Map<Integer,String>> classNames =  classGroupDao.queryNamesByClassId(classGroupIdStr);
//			Map<Integer,String> classNameMap = MapUtil.convertMybatisMap(classNames);

			dataList.forEach(e->{
//				e.setCourseScheduleName(classNameMap.get(e.getClassGroupId()));
				e.setNum(signNumMap.get(e.getTeacherId()));
			});
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

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

		List<MusicGroupTeacherAttendanceDto> dataList = null;
		int count = teacherDao.countTeacherAttendance(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = teacherDao.queryTeacherAttendance(params);
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

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

		List<musicGroupStudentApplyDto> dataList = null;
		int count = teacherDao.countMusicGroupStudentApply(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = teacherDao.queryMusicGroupStudentApply(params);
			String paymentStatus = queryInfo.getPaymentStatus();
			if(StringUtils.isNotEmpty(paymentStatus) && paymentStatus.equals("2")){
				List<StudentPaymentOrder> studentPaymentOrders = studentPaymentOrderDao.findStudentPaymentOrder("MUSIC",queryInfo.getMusicGroupId());
				Map<Integer, List<StudentPaymentOrder>> collect = studentPaymentOrders.stream().collect(Collectors.groupingBy(StudentPaymentOrder::getUserId));
				dataList.forEach(e->{
					List<StudentPaymentOrder> paymentOrders = collect.get(e.getUserId());
					if(paymentOrders != null && paymentOrders.size() > 0){
						e.setPaymentAmount(paymentOrders.get(0).getActualAmount());
						e.setPayTime(paymentOrders.get(0).getPayTime());
					}
				});
			}
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public List<Teacher> findTeacherByOrganId(String organId,String subjectIds,String jobNature) {
		return teacherDao.findTeacherByOrganId(organId,subjectIds,jobNature);
	}

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

		List<Teacher> dataList = null;
		int count = teacherDao.countTeacherName(params);
		if (count > 0) {
			pageInfo.setTotal(count);
			params.put("offset", pageInfo.getOffset());
			dataList = teacherDao.queryPageName(params);
		}
		if (count == 0) {
			dataList = new ArrayList<>();
		}
		pageInfo.setRows(dataList);
		return pageInfo;
	}

	@Override
	public CourseHomework getCourseScheduleHomework(Integer courseScheduleId) {
		return teacherDao.getCourseScheduleHomework(courseScheduleId);
	}

	@Override
	public List<BasicUserDto> queryEducationIpa(Integer userId, String search) {
		List<BasicUserDto> basicUserDtos = queryGroupStudents(userId, search);
		//获取当前管理人员所在分部，所有老师，以及没有乐团的学生
		List<BasicUserDto> userDtos = teacherDao.queryEducationIpa(userId, search);
		userDtos.addAll(basicUserDtos);
		return userDtos.stream().distinct().collect(Collectors.toList());
	}

	@Override
	public List<BasicUserDto> queryMusicGroupTeacher(String musicGroupId) {
		if(Objects.isNull(musicGroupId)){
			throw new BizException("请指定乐团");
		}
		return teacherDao.findTeacherByMusicGroup(musicGroupId);
	}

	@Override
	public PageInfo<Teacher> queryPageDetail(TeacherQueryInfo queryInfo) {
		Map<String, Object> params = new HashMap<>();
		MapUtil.populateMap(params, queryInfo);
		List<Teacher> teacherList = teacherDao.findByFlowOrganRange(params);
		if(teacherList == null || teacherList.size() < 1){
			return new PageInfo<>();
		}
		if(StringUtils.isNotEmpty(queryInfo.getOrganId())){
			Set<String> list = new HashSet<>(Arrays.asList(queryInfo.getOrganId().split(",")));
			teacherList = teacherList.stream().
					filter(teacher -> !Collections.disjoint(new ArrayList<>(Arrays.asList(teacher.getFlowOrganRange().split(","))),list)).collect(Collectors.toList());
		}
		List<Integer> collect = teacherList.stream().map(e -> e.getId()).collect(Collectors.toList());
		if(collect == null || collect.size() < 1){
			return new PageInfo<>();
		}
		queryInfo.setTeacherId(collect);

		PageInfo<Teacher> pageInfo = queryPage(queryInfo);
		List<Teacher> rows = pageInfo.getRows();
		if(rows != null && rows.size() > 0){
			Set<Integer> teachers = rows.stream().map(e -> e.getId()).collect(Collectors.toSet());
			String teacherIds = StringUtils.join(teachers, ",");
			//获取小课数量
			Map<Integer,Integer> vipNumMap = JSONObject.parseObject(JSONObject.toJSONString(MapUtil.convertIntegerMap(classGroupDao.countTeacherVipNum(teacherIds))),HashMap.class);
			//获取试听课数量
			Map<Integer,Integer> demoNumMap = JSONObject.parseObject(JSONObject.toJSONString(MapUtil.convertIntegerMap(demoGroupDao.countTeacherDemoGroupNum(teacherIds))),HashMap.class);

			Set<Integer> organIds = rows.stream().map(e -> e.getTeacherOrganId()).collect(Collectors.toSet());
			Map<Integer,String> organNames = MapUtil.convertMybatisMap(organizationDao.findOrganNameMapList(organIds));
			rows.forEach(e->{
//				e.setSubjectName(subjectDao.findBySubIds(e.getSubjectId()));
				e.setOrganName(organNames.get(e.getTeacherOrganId()));
				if(StringUtils.isNotEmpty(e.getSplitSubjectName())){
					e.setSubjectName(Arrays.asList(e.getSplitSubjectName().split(",")));
				}
				Integer num = vipNumMap.get(e.getId());
				e.setVipNum(num == null?0:num);
				Integer demoNum = demoNumMap.get(e.getId());
				e.setDemoNum(demoNum == null?0:demoNum);
			});
		}
		return pageInfo;
	}

	@Override
	public Teacher getDetail(Integer id) {
		Teacher teacher = teacherDao.get(id);
		if(teacher != null){
			//获取老师教学点列表
			List<School> teacherSchools = schoolDao.findByUserId(id);
			teacher.setTeacherSchools(teacherSchools);
			//获取流动范围
			if(StringUtils.isNotEmpty(teacher.getFlowOrganRange())){
				teacher.setFlowOrganRangeId(teacher.getFlowOrganRange());
				List<String> organNames = organizationDao.findByOrganIds(teacher.getFlowOrganRange());
				teacher.setFlowOrganRange(StringUtils.join(organNames,","));
			}
			if(teacher.getTeacherOrganId() != null){
				teacher.setOrganName(organizationDao.get(teacher.getTeacherOrganId()).getName());
			}
			//专业技能
			if(StringUtils.isNotEmpty(teacher.getSubjectId())){
				teacher.setSubjectName(subjectDao.findBySubIds(teacher.getSubjectId()));
			}
		}
		return teacher;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean realNameAuthentication(Integer userId, String realName, String idcardNo, String idcardFrontImg, String idcardBackImg, String idcardHandImg) {

		SysUser user = sysUserFeignService.queryUserById(userId);
		if (user == null) {
			throw new BizException("用户不存在");
		}

		Teacher teacher = teacherDao.get(userId);
		if (teacher == null) {
			throw new BizException("用户信息不存在");
		}
		// 查询是否已实名认证
		if (StringUtils.isNotBlank(teacher.getIdcardBackImg()) && StringUtils.isNotBlank(teacher.getIdcardFrontImg())
				&& StringUtils.isNotBlank(teacher.getIdcardHandImg())) {
			throw new BizException("已实名认证，不能重复操作");
		}
		
		IdcardValidator validator = new IdcardValidator();
		if (validator.isValidatedAllIdcard(idcardNo) == false) {
			throw new BizException("身份证校验失败");
		}

		Date date = new Date();

		user.setRealName(realName);
		user.setIdCardNo(idcardNo);
		user.setUpdateTime(date);
		sysUserFeignService.updateSysUser(user);

		teacher.setIdcardBackImg(idcardBackImg);
		teacher.setIdcardFrontImg(idcardFrontImg);
		teacher.setIdcardHandImg(idcardHandImg);
		teacher.setUpdateTime(date);
		teacherDao.update(teacher);

		return true;
	}

}
