package com.xinyilu.system.service.teacherInfo.impl;

import com.xinyilu.common.constant.Constants;
import com.xinyilu.common.core.domain.AjaxResult;
import com.xinyilu.common.core.domain.entity.SysRole;
import com.xinyilu.common.core.page.TableDataInfo;
import com.xinyilu.common.exception.ServiceException;
import com.xinyilu.common.utils.DateUtils;
import com.xinyilu.common.utils.PageServiceUtil;
import com.xinyilu.common.utils.SecurityUtils;
import com.xinyilu.system.domain.classinfo.ClassInfo;
import com.xinyilu.system.domain.dto.TeacherInfoDTO;
import com.xinyilu.system.domain.systemarea.SysArea;
import com.xinyilu.system.domain.teacherInfo.ClassTeacherInfo;
import com.xinyilu.system.domain.teacherInfo.TeacherInfo;
import com.xinyilu.system.domain.vo.SysUserVO;
import com.xinyilu.system.domain.vo.TeacherInfoVO;
import com.xinyilu.system.domain.vo.teacherInfo.UserTeacherVO;
import com.xinyilu.system.mapper.SysUserMapper;
import com.xinyilu.system.mapper.classinfo.ClassInfoMapper;
import com.xinyilu.system.mapper.systemarea.SysAreaMapper;
import com.xinyilu.system.mapper.teacherInfo.ClassTeacherInfoMapper;
import com.xinyilu.system.mapper.teacherInfo.TeacherInfoMapper;
import com.xinyilu.system.service.teacherInfo.ITeacherInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
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;


/**
 * 教师信息管理Service业务层处理
 *
 * @author jihan
 * @date 2022-08-05
 */
@Slf4j
@Service
public class TeacherInfoServiceImpl implements ITeacherInfoService {
    @Resource
    private TeacherInfoMapper teacherInfoMapper;
    @Resource
    private ClassTeacherInfoMapper classTeacherInfoMapper;
    @Resource
    private PageServiceUtil pageServiceUtil;
    @Resource
    private ClassInfoMapper classInfoMapper;
    @Resource
    private SysUserMapper userMapper;
    @Resource
    private SysAreaMapper sysAreaMapper;

    /**
     * 查询教师信息管理
     *
     * @param id 教师信息管理主键
     * @return 教师信息管理
     */
    @Override
    public TeacherInfoVO selectTeacherInfoById(Long id) {
        return teacherInfoMapper.selectTeacherInfoById(id);
    }

    /**
     * 查询教师信息管理列表
     *
     * @param teacherInfo 教师信息管理
     * @return 教师信息管理
     */
    @Override
    public TableDataInfo selectTeacherInfoList(TeacherInfoDTO teacherInfo) {
        //判断当前用户角色，根据不同的角色显示不同的教师信息
        List<String> roleKeys = SecurityUtils.getLoginUser().getUser().getRoles()
                .stream().filter(Objects::nonNull)
                .filter(item -> StringUtils.isNotBlank(item.getRoleKey()))
                .map(SysRole::getRoleKey).collect(Collectors.toList());
        Long userId = SecurityUtils.getUserId();
        SysUserVO sysUserVO = userMapper.selectUserById(userId);
        if (roleKeys.contains(Constants.ADMIN_ROLE)) {
            //管理员，查询所有的教师信息
            return getTeacherInfoList(teacherInfo);
        } else if (roleKeys.contains(Constants.CITY)) {
            //市级角色，查询该市级下所有幼儿园的教师信息
            long areaId = Objects.isNull(SecurityUtils.getLoginUser().getUser().getAreaId()) ? 0 : SecurityUtils.getLoginUser().getUser().getAreaId();
            SysArea sysArea = new SysArea();
            sysArea.setParentId(areaId);
            List<Long> sysAreaIdList = sysAreaMapper.selectSysAreaList(sysArea).stream().filter(Objects::nonNull).filter(sysAreaId -> Objects.nonNull(sysAreaId.getId())).map(SysArea::getId).collect(Collectors.toList());
            List<Long> kindergartenIdList = Lists.newArrayList();
            if (CollectionUtils.isNotEmpty(sysAreaIdList)) {
                //获取该区域下的所有幼儿园信息
                kindergartenIdList = classInfoMapper.getKindergartenInfoByAreaId(sysAreaIdList, null);
            }
            if (CollectionUtils.isEmpty(kindergartenIdList)) {
                return null;
            }
            teacherInfo.setKindergartenIdList(kindergartenIdList);
            return getTeacherInfoList(teacherInfo);
        } else if (roleKeys.contains(Constants.REGION_ROLE)) {
            //区域角色，查询该区域下所有幼儿园的教师信息
            long areaId = Objects.isNull(SecurityUtils.getLoginUser().getUser().getAreaId()) ? 0 : SecurityUtils.getLoginUser().getUser().getAreaId();
            List<Long> kindergartenIdList = Lists.newArrayList();
            List<Long> sysAreaIdList = new ArrayList<>();
            sysAreaIdList.add(areaId);
            if (CollectionUtils.isNotEmpty(sysAreaIdList)) {
                //获取该区域下的所有幼儿园信息
                kindergartenIdList = classInfoMapper.getKindergartenInfoByAreaId(sysAreaIdList, 3L);
            }
            if (CollectionUtils.isEmpty(kindergartenIdList)) {
                return null;
            }
            teacherInfo.setKindergartenIdList(kindergartenIdList);
            return getTeacherInfoList(teacherInfo);
        } else if (roleKeys.contains(Constants.ENCHOU_ROLE)) {
            //园长角色，查询该幼儿园下的所有教师信息
            Long kindergartenId = classInfoMapper.getKindergartenIdByPrincipalId(userId);
            if (Objects.isNull(kindergartenId) || kindergartenId == 0L) {
                return null;
            }
            teacherInfo.setKindergartenId(kindergartenId);
            return getTeacherInfoList(teacherInfo);
        } else if (roleKeys.contains(Constants.HEALTHCARE_ROLE)) {
            //角色是：保健师，查找出其所属的幼儿园信息
            if (Objects.isNull(sysUserVO) || Objects.isNull(sysUserVO.getKindergartenId())) {
                return null;
            }
            teacherInfo.setKindergartenId(sysUserVO.getKindergartenId());
            return getTeacherInfoList(teacherInfo);
        } else if (roleKeys.contains(Constants.TEACHER_ROLE) && roleKeys.size() == 1) {
            if (Objects.isNull(sysUserVO) || Objects.isNull(sysUserVO.getKindergartenId()) || Objects.isNull(sysUserVO.getUserName())) {
                return null;
            }
            //老师角色，查询自己的信息
            UserTeacherVO userTeacherList = teacherInfoMapper.getUserTeacher(sysUserVO.getUserName(), sysUserVO.getKindergartenId());
            if (Objects.isNull(userTeacherList) || Objects.isNull(userTeacherList.getTeacherId())) {
                return null;
            }
            //更新教师userId
            teacherInfoMapper.updateTeacherInfoByUserId(userTeacherList.getTeacherId(), userId);
            teacherInfo.setId(userTeacherList.getTeacherId());
            return getTeacherInfoList(teacherInfo);
        } else if (roleKeys.contains(Constants.PARENT_ROLE) && roleKeys.size() == 1) {
            //家长角色，查询其孩子所在班级的教师的信息
            if (Objects.isNull(sysUserVO) || Objects.isNull(sysUserVO.getPhonenumber())) {
                return null;
            }
            List<Long> teacherIdByUserId = teacherInfoMapper.getTeacherIdByUserId(sysUserVO.getPhonenumber());
            if (CollectionUtils.isEmpty(teacherIdByUserId)) {
                return null;
            }
            teacherInfo.setTeacherIdList(teacherIdByUserId);
            return getTeacherInfoList(teacherInfo);
        } else if (roleKeys.contains(Constants.TEACHER_ROLE) && roleKeys.contains(Constants.PARENT_ROLE) && roleKeys.size() == 2) {
            //即是老师角色又是家长角色，查询自己孩子班级中老师的信息和自己的信息
            teacherInfo.setRoleUserId(userId);
            List<Long> teacherIdByUserId = new ArrayList<>();
            if (Objects.nonNull(sysUserVO) && Objects.nonNull(sysUserVO.getPhonenumber())) {
                teacherIdByUserId = teacherInfoMapper.getTeacherIdByUserId(sysUserVO.getPhonenumber());
            }
            // 如果是老师
            UserTeacherVO userTeacherList = teacherInfoMapper.getUserTeacher(sysUserVO.getUserName(), sysUserVO.getKindergartenId());
            if (Objects.nonNull(userTeacherList) && Objects.nonNull(userTeacherList.getTeacherId())) {
                teacherIdByUserId.add(userTeacherList.getTeacherId());
            }
            if (CollectionUtils.isEmpty(teacherIdByUserId)) {
                return null;
            }
            teacherInfo.setRoleTeacherIdList(teacherIdByUserId);
            return getTeacherInfoList(teacherInfo);
        }
        return null;
    }

    /**
     * 新增教师信息管理
     *
     * @param teacherInfo 教师信息管理
     * @param createBy    创建人
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertTeacherInfo(TeacherInfoDTO teacherInfo, String createBy) {
        //校验身份证号和手机号是否为空
        AjaxResult ajaxResult = judgeParam(teacherInfo, false);
        if (Objects.nonNull(ajaxResult)) {
            return ajaxResult;
        }
        teacherInfo.setCreateTime(DateUtils.getNowDate());
        teacherInfo.setCreateBy(createBy);
        teacherInfo.setDelFlag(0);
        teacherInfo.setUserId(SecurityUtils.getUserId());
        //新增教师主表信息
        int insertTeacherCount = teacherInfoMapper.insertTeacherInfo(teacherInfo);
        if (insertTeacherCount <= 0) {
            throw new ServiceException("新增教师信息失败");
        }
        //新怎班级教师关系表
        return insertClassTeacherInfo(teacherInfo, createBy);
    }

    /**
     * 修改教师信息管理
     *
     * @param teacherInfo 教师信息管理
     * @param updateBy    修改人
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateTeacherInfo(TeacherInfoDTO teacherInfo, String updateBy) {
        //校验身份证号和手机号是否为空
        AjaxResult ajaxResult = judgeParam(teacherInfo, true);
        if (Objects.nonNull(ajaxResult)) {
            return ajaxResult;
        }
        teacherInfo.setUpdateTime(DateUtils.getNowDate());
        teacherInfo.setUpdateBy(updateBy);
        teacherInfo.setDelFlag(0);
        int updateTeacherCount = teacherInfoMapper.updateTeacherInfo(teacherInfo);
        if (updateTeacherCount <= 0) {
            throw new ServiceException("修改教师信息失败");
        }
        //删除班级教师关系表信息
        int deleteClassTeacherCount = classTeacherInfoMapper.deleteClassTeacherInfoById(teacherInfo.getId());
        if (deleteClassTeacherCount <= 0) {
            log.info("删除班级教师关系表信息失败，id=[{}]", teacherInfo.getId());
            throw new ServiceException("修改教师信息失败");
        }
        //新增班级教师关系表信息
        return insertClassTeacherInfo(teacherInfo, updateBy);
    }

    /**
     * 批量删除教师信息管理
     *
     * @param ids 需要删除的教师信息管理主键
     * @return 结果
     */
    @Override
    public int deleteTeacherInfoByIds(Long[] ids) {
        return teacherInfoMapper.deleteTeacherInfoByIds(ids);
    }

    /**
     * 删除教师信息管理信息
     *
     * @param id 教师信息管理主键
     * @return 结果
     */
    @Override
    public int deleteTeacherInfoById(Long id) {
        return teacherInfoMapper.deleteTeacherInfoById(id);
    }

    /**
     * 判断身份证号和手机号是否唯一
     *
     * @param teacherInfo 教师信息
     * @param flag        新增和删除标志
     * @return AjaxResult 校验结果
     */
    private AjaxResult judgeParam(TeacherInfoDTO teacherInfo, boolean flag) {
        if (CollectionUtils.isEmpty(teacherInfo.getClassInfoList())) {
            return AjaxResult.error("所属班级信息不能为空");
        }
        if (BooleanUtils.isTrue(flag)) {
            //修改校验
            TeacherInfoVO teacherInfoVO = teacherInfoMapper.selectTeacherInfoById(teacherInfo.getId());
            if (Objects.isNull(teacherInfoVO)) {
                return AjaxResult.error("教师信息不存在");
            }
            // 如果身份证号不为空 才进行校验
            if (StringUtils.isNotBlank(teacherInfo.getCardNo())) {
                //身份证号
                if (StringUtils.isNotBlank(teacherInfo.getCardNo()) && !teacherInfo.getCardNo().equals(teacherInfoVO.getCardNo())) {
                    TeacherInfo teacher = new TeacherInfo();
                    teacher.setCardNo(StringUtils.isBlank(teacherInfo.getCardNo()) ? "" : teacherInfo.getCardNo());
                    int cardNoCount = teacherInfoMapper.selectTeacherInfo(teacher);
                    if (cardNoCount > 0) {
                        return AjaxResult.error("证件号已存在，请重新填写");
                    }
                }
            }
            //手机号
            if (StringUtils.isNotBlank(teacherInfo.getTeacherPhone()) && !teacherInfo.getTeacherPhone().equals(teacherInfoVO.getTeacherPhone())) {
                TeacherInfo teacher = new TeacherInfo();
                teacher.setTeacherPhone(StringUtils.isBlank(teacherInfo.getTeacherPhone()) ? "" : teacherInfo.getTeacherPhone());
                int phoneCount = teacherInfoMapper.selectTeacherInfo(teacher);
                if (phoneCount > 0) {
                    return AjaxResult.error("手机号已存在，请重新填写");
                }
            }
        } else {
            //新增校验
            TeacherInfo teacher = new TeacherInfo();
            if (StringUtils.isNotBlank(teacherInfo.getCardNo())) {
                teacher.setCardNo(StringUtils.isBlank(teacherInfo.getCardNo()) ? "" : teacherInfo.getCardNo());
                int cardNoCount = teacherInfoMapper.selectTeacherInfo(teacher);
                if (cardNoCount > 0) {
                    return AjaxResult.error("证件号已存在，请重新填写");
                }
            }
            if (StringUtils.isNotBlank(teacherInfo.getTeacherPhone())) {
                teacher.setCardNo(null);
                teacher.setTeacherPhone(teacherInfo.getTeacherPhone());
                int phoneCount = teacherInfoMapper.selectTeacherInfo(teacher);
                if (phoneCount > 0) {
                    return AjaxResult.error("手机号已存在，请重新填写");
                }
            }
        }
        return null;
    }

    /**
     * 新增班级教师关系表信息
     *
     * @param teacherInfo 班级教师信息
     * @param updateBy    修改人
     * @return 结果
     */
    private AjaxResult insertClassTeacherInfo(TeacherInfoDTO teacherInfo, String updateBy) {
        for (Long classId : teacherInfo.getClassInfoList()) {
            ClassTeacherInfo classTeacherInfo = new ClassTeacherInfo();
            classTeacherInfo.setClassId(classId);
            classTeacherInfo.setTeacherId(teacherInfo.getId());
            classTeacherInfo.setDelFlag(0);
            classTeacherInfo.setCreateBy(updateBy);
            classTeacherInfo.setCreateTime(DateUtils.getNowDate());
            int classTeacherInfoCount = classTeacherInfoMapper.insertClassTeacherInfo(classTeacherInfo);
            if (classTeacherInfoCount <= 0) {
                throw new ServiceException("新增班级教师关系信息失败");
            }
        }
        return AjaxResult.success();
    }

    /**
     * 逻辑批量删除教师信息管理
     *
     * @param ids 需要删除的教师信息管理主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateTeacherInfoByIds(Long[] ids) {
        //删除教师表信息
        int updateTeacherInfoCount = teacherInfoMapper.updateTeacherInfoByIds(ids);
        if (updateTeacherInfoCount <= 0) {
            throw new ServiceException("删除教师关系信息失败");
        }
        //删除班级教师关系表信息
        int classTeacherInfoCount = classTeacherInfoMapper.updateClassTeacherInfoByIds(ids);
        if (classTeacherInfoCount <= 0) {
            throw new ServiceException("删除教师关系信息失败");
        }
        return AjaxResult.success();
    }

    /**
     * 根据教师表id查询对应得班级信息
     *
     * @param id 教师表id
     * @return List<ClassInfo> 班级信息集合
     */
    @Override
    public List<ClassInfo> getClassInfoList(Long id) {
        return classTeacherInfoMapper.getClassInfoList(id);
    }

    /**
     * 分页查询教师列表信息
     *
     * @param teacherInfo 输入参数
     * @return 教师列表信息
     */
    private TableDataInfo getTeacherInfoList(TeacherInfoDTO teacherInfo) {
        pageServiceUtil.startPage();
        List<TeacherInfoVO> teacherInfoList = teacherInfoMapper.selectTeacherInfoList(teacherInfo);
        return pageServiceUtil.getDataTable(teacherInfoList);
    }
}
