package com.xjrsoft.module.teacher.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.enums.RoleEnum;
import com.xjrsoft.common.utils.RedisUtil;
import com.xjrsoft.config.CommonPropertiesConfig;
import com.xjrsoft.module.organization.entity.User;
import com.xjrsoft.module.organization.entity.UserDeptRelation;
import com.xjrsoft.module.organization.entity.UserRoleRelation;
import com.xjrsoft.module.organization.mapper.UserDeptRelationMapper;
import com.xjrsoft.module.organization.mapper.UserRoleRelationMapper;
import com.xjrsoft.module.organization.service.IUserDeptRelationService;
import com.xjrsoft.module.organization.service.IUserService;
import com.xjrsoft.module.teacher.dto.AddXjrUserDto;
import com.xjrsoft.module.teacher.dto.UpdateXjrUserDto;
import com.xjrsoft.module.teacher.entity.BaseTeacher;
import com.xjrsoft.module.teacher.entity.BaseTeacherContact;
import com.xjrsoft.module.teacher.entity.BaseTeacherEducation;
import com.xjrsoft.module.teacher.entity.BaseTeacherEmploy;
import com.xjrsoft.module.teacher.entity.BaseTeacherFamily;
import com.xjrsoft.module.teacher.entity.BaseTeacherFamilyMember;
import com.xjrsoft.module.teacher.entity.BaseTeacherRegular;
import com.xjrsoft.module.teacher.entity.XjrUser;
import com.xjrsoft.module.teacher.mapper.BaseTeacherContactMapper;
import com.xjrsoft.module.teacher.mapper.BaseTeacherEducationMapper;
import com.xjrsoft.module.teacher.mapper.BaseTeacherEmployMapper;
import com.xjrsoft.module.teacher.mapper.BaseTeacherFamilyMapper;
import com.xjrsoft.module.teacher.mapper.BaseTeacherFamilyMemberMapper;
import com.xjrsoft.module.teacher.mapper.BaseTeacherMapper;
import com.xjrsoft.module.teacher.mapper.BaseTeacherRegularMapper;
import com.xjrsoft.module.teacher.mapper.XjrUserMapper;
import com.xjrsoft.module.teacher.service.ITeacherbaseManagerService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
* @title: service
* @Author 管理员
* @Date: 2023-08-08
* @Version 1.0
*/
@Service
@AllArgsConstructor
public class TeacherbaseManagerServiceImpl extends MPJBaseServiceImpl<XjrUserMapper, XjrUser> implements ITeacherbaseManagerService {
    private final XjrUserMapper teacherbaseManagerXjrUserMapper;

    private final BaseTeacherMapper teacherbaseManagerBaseTeacherMapper;
    private final BaseTeacherContactMapper teacherbaseManagerBaseTeacherContactMapper;
    private final BaseTeacherEducationMapper teacherbaseManagerBaseTeacherEducationMapper;
    private final BaseTeacherEmployMapper teacherbaseManagerBaseTeacherEmployMapper;
    private final BaseTeacherFamilyMapper teacherbaseManagerBaseTeacherFamilyMapper;
    private final BaseTeacherFamilyMemberMapper teacherbaseManagerBaseTeacherFamilyMemberMapper;
    private final BaseTeacherRegularMapper teacherbaseManagerBaseTeacherRegularMapper;

    private final UserRoleRelationMapper userRoleRelationMapper;
    private final IUserDeptRelationService userDeptRelationService;
    private final RedisUtil redisUtil;
    private final UserDeptRelationMapper userDeptRelationMapper;
    private final IUserService userService;
    private final CommonPropertiesConfig propertiesConfig;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(AddXjrUserDto dto) {

        XjrUser xjrUser = BeanUtil.toBean(dto, XjrUser.class);
        xjrUser.setCode(dto.getUserName());

        // 使用系统配置的默认密码
        xjrUser.setPassword(BCrypt.hashpw(propertiesConfig.getDefaultPassword(), BCrypt.gensalt()));
        teacherbaseManagerXjrUserMapper.insert(xjrUser);
        for (BaseTeacher baseTeacher : xjrUser.getBaseTeacherList()) {
            baseTeacher.setUserId(xjrUser.getId());
            teacherbaseManagerBaseTeacherMapper.insert(baseTeacher);
        }
        for (BaseTeacherContact baseTeacherContact : xjrUser.getBaseTeacherContactList()) {
            baseTeacherContact.setUserId(xjrUser.getId());
            teacherbaseManagerBaseTeacherContactMapper.insert(baseTeacherContact);
        }
        for (BaseTeacherEducation baseTeacherEducation : xjrUser.getBaseTeacherEducationList()) {
            baseTeacherEducation.setUserId(xjrUser.getId());
            teacherbaseManagerBaseTeacherEducationMapper.insert(baseTeacherEducation);
        }
        for (BaseTeacherEmploy baseTeacherEmploy : xjrUser.getBaseTeacherEmployList()) {
            baseTeacherEmploy.setUserId(xjrUser.getId());
            teacherbaseManagerBaseTeacherEmployMapper.insert(baseTeacherEmploy);
        }
        for (BaseTeacherFamily baseTeacherFamily : xjrUser.getBaseTeacherFamilyList()) {
            baseTeacherFamily.setUserId(xjrUser.getId());
            teacherbaseManagerBaseTeacherFamilyMapper.insert(baseTeacherFamily);
        }
        for (BaseTeacherFamilyMember baseTeacherFamilyMember : xjrUser.getBaseTeacherFamilyMemberList()) {
            baseTeacherFamilyMember.setUserId(xjrUser.getId());
            teacherbaseManagerBaseTeacherFamilyMemberMapper.insert(baseTeacherFamilyMember);
        }
        for (BaseTeacherRegular baseTeacherRegular : xjrUser.getBaseTeacherRegularList()) {
            baseTeacherRegular.setUserId(xjrUser.getId());
            teacherbaseManagerBaseTeacherRegularMapper.insert(baseTeacherRegular);
        }

        List<UserDeptRelation> userDeptRelationList = new ArrayList<>();
        if (StrUtil.isNotBlank(dto.getDepartmentIds())) {
            String allDeptIdStr = StrUtil.join(StringPool.COMMA, dto.getDepartmentIds());
            List<Long> departmentIds = Arrays.stream(allDeptIdStr.split(StringPool.COMMA)).map(Convert::toLong).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(departmentIds)) {
                for (Long deptId : departmentIds) {
                    //将用户所选部门保存到关联表中
                    UserDeptRelation userDeptRelation = new UserDeptRelation();
                    userDeptRelation.setUserId(xjrUser.getId());
                    userDeptRelation.setDeptId(deptId);
                    userDeptRelationList.add(userDeptRelation);
                }
            }
            userDeptRelationService.saveBatch(userDeptRelationList);
        }

        // 添加角色
        UserRoleRelation userRoleRelation = new UserRoleRelation();
        userRoleRelation.setUserId(xjrUser.getId());
        userRoleRelation.setRoleId(RoleEnum.TEACHER.getCode());
        userRoleRelationMapper.insert(userRoleRelation);

        List<User> list = userService.list();
        list.add(BeanUtil.toBean(xjrUser, User.class));
        redisUtil.set(GlobalConstant.USER_CACHE_KEY, list);


        List<UserDeptRelation> deptRelationList = userDeptRelationMapper.selectList(Wrappers.lambdaQuery(UserDeptRelation.class));
        redisUtil.set(GlobalConstant.USER_DEPT_RELATION_CACHE_KEY, deptRelationList);

        List<UserRoleRelation> userRoleRelationList = userRoleRelationMapper.selectList(Wrappers.lambdaQuery(UserRoleRelation.class));
        redisUtil.set(GlobalConstant.USER_ROLE_RELATION_CACHE_KEY, userRoleRelationList);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(UpdateXjrUserDto dto) {

        XjrUser xjrUser = BeanUtil.toBean(dto, XjrUser.class);

        teacherbaseManagerXjrUserMapper.updateById(xjrUser);

        //先删除再新增
        userDeptRelationService.remove(Wrappers.<UserDeptRelation>query().lambda().eq(UserDeptRelation::getUserId, xjrUser.getId()));
        List<UserDeptRelation> userDeptRelationList = new ArrayList<>();
        if (StrUtil.isNotBlank(dto.getDepartmentIds())) {
            String allDeptIdStr = StrUtil.join(StringPool.COMMA, dto.getDepartmentIds());
            List<Long> departmentIds = Arrays.stream(allDeptIdStr.split(StringPool.COMMA)).map(Convert::toLong).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(departmentIds)) {
                for (Long deptId : departmentIds) {
                    //将用户所选部门保存到关联表中
                    UserDeptRelation userDeptRelation = new UserDeptRelation();
                    userDeptRelation.setUserId(xjrUser.getId());
                    userDeptRelation.setDeptId(deptId);
                    userDeptRelationList.add(userDeptRelation);
                }
            }
            userDeptRelationService.saveBatch(userDeptRelationList);
        }

        //********************************* BaseTeacher  增删改  开始 *******************************************/
        {
            // 查出所有子级的id
            List<BaseTeacher> baseTeacherList = teacherbaseManagerBaseTeacherMapper.selectList(Wrappers.lambdaQuery(BaseTeacher.class).eq(BaseTeacher::getUserId, xjrUser.getId()).select(BaseTeacher::getId));
            List<Long> baseTeacherIds = baseTeacherList.stream().map(BaseTeacher::getId).collect(Collectors.toList());
            //原有子表单 没有被删除的主键
            List<Long> baseTeacherOldIds = xjrUser.getBaseTeacherList().stream().map(BaseTeacher::getId).filter(Objects::nonNull).collect(Collectors.toList());
            //找到需要删除的id
            List<Long> baseTeacherRemoveIds = baseTeacherIds.stream().filter(item -> !baseTeacherOldIds.contains(item)).collect(Collectors.toList());

            for (BaseTeacher baseTeacher : xjrUser.getBaseTeacherList()) {
                //如果不等于空则修改
                if (baseTeacher.getId() != null) {
                    teacherbaseManagerBaseTeacherMapper.updateById(baseTeacher);
                }
                //如果等于空 则新增
                else {
                    //已经不存在的id 删除
                    baseTeacher.setUserId(xjrUser.getId());
                    teacherbaseManagerBaseTeacherMapper.insert(baseTeacher);
                }
            }
            //已经不存在的id 删除
            if(baseTeacherRemoveIds.size() > 0){
                teacherbaseManagerBaseTeacherMapper.deleteBatchIds(baseTeacherRemoveIds);
            }
        }
        //********************************* BaseTeacher  增删改  结束 *******************************************/

        //********************************* BaseTeacherContact  增删改  开始 *******************************************/
        {
            // 查出所有子级的id
            List<BaseTeacherContact> baseTeacherContactList = teacherbaseManagerBaseTeacherContactMapper.selectList(Wrappers.lambdaQuery(BaseTeacherContact.class).eq(BaseTeacherContact::getUserId, xjrUser.getId()).select(BaseTeacherContact::getId));
            List<Long> baseTeacherContactIds = baseTeacherContactList.stream().map(BaseTeacherContact::getId).collect(Collectors.toList());
            //原有子表单 没有被删除的主键
            List<Long> baseTeacherContactOldIds = xjrUser.getBaseTeacherContactList().stream().map(BaseTeacherContact::getId).filter(Objects::nonNull).collect(Collectors.toList());
            //找到需要删除的id
            List<Long> baseTeacherContactRemoveIds = baseTeacherContactIds.stream().filter(item -> !baseTeacherContactOldIds.contains(item)).collect(Collectors.toList());

            for (BaseTeacherContact baseTeacherContact : xjrUser.getBaseTeacherContactList()) {
                //如果不等于空则修改
                if (baseTeacherContact.getId() != null) {
                    teacherbaseManagerBaseTeacherContactMapper.updateById(baseTeacherContact);
                }
                //如果等于空 则新增
                else {
                    //已经不存在的id 删除
                    baseTeacherContact.setUserId(xjrUser.getId());
                    teacherbaseManagerBaseTeacherContactMapper.insert(baseTeacherContact);
                }
            }
            //已经不存在的id 删除
            if(baseTeacherContactRemoveIds.size() > 0){
                teacherbaseManagerBaseTeacherContactMapper.deleteBatchIds(baseTeacherContactRemoveIds);
            }
        }
        //********************************* BaseTeacherContact  增删改  结束 *******************************************/

        //********************************* BaseTeacherEducation  增删改  开始 *******************************************/
        {
            // 查出所有子级的id
            List<BaseTeacherEducation> baseTeacherEducationList = teacherbaseManagerBaseTeacherEducationMapper.selectList(Wrappers.lambdaQuery(BaseTeacherEducation.class).eq(BaseTeacherEducation::getUserId, xjrUser.getId()).select(BaseTeacherEducation::getId));
            List<Long> baseTeacherEducationIds = baseTeacherEducationList.stream().map(BaseTeacherEducation::getId).collect(Collectors.toList());
            //原有子表单 没有被删除的主键
            List<Long> baseTeacherEducationOldIds = xjrUser.getBaseTeacherEducationList().stream().map(BaseTeacherEducation::getId).filter(Objects::nonNull).collect(Collectors.toList());
            //找到需要删除的id
            List<Long> baseTeacherEducationRemoveIds = baseTeacherEducationIds.stream().filter(item -> !baseTeacherEducationOldIds.contains(item)).collect(Collectors.toList());

            for (BaseTeacherEducation baseTeacherEducation : xjrUser.getBaseTeacherEducationList()) {
                //如果不等于空则修改
                if (baseTeacherEducation.getId() != null) {
                    teacherbaseManagerBaseTeacherEducationMapper.updateById(baseTeacherEducation);
                }
                //如果等于空 则新增
                else {
                    //已经不存在的id 删除
                    baseTeacherEducation.setUserId(xjrUser.getId());
                    teacherbaseManagerBaseTeacherEducationMapper.insert(baseTeacherEducation);
                }
            }
            //已经不存在的id 删除
            if(baseTeacherEducationRemoveIds.size() > 0){
                teacherbaseManagerBaseTeacherEducationMapper.deleteBatchIds(baseTeacherEducationRemoveIds);
            }
        }
        //********************************* BaseTeacherEducation  增删改  结束 *******************************************/

        //********************************* BaseTeacherEmploy  增删改  开始 *******************************************/
        {
            // 查出所有子级的id
            List<BaseTeacherEmploy> baseTeacherEmployList = teacherbaseManagerBaseTeacherEmployMapper.selectList(Wrappers.lambdaQuery(BaseTeacherEmploy.class).eq(BaseTeacherEmploy::getUserId, xjrUser.getId()).select(BaseTeacherEmploy::getId));
            List<Long> baseTeacherEmployIds = baseTeacherEmployList.stream().map(BaseTeacherEmploy::getId).collect(Collectors.toList());
            //原有子表单 没有被删除的主键
            List<Long> baseTeacherEmployOldIds = xjrUser.getBaseTeacherEmployList().stream().map(BaseTeacherEmploy::getId).filter(Objects::nonNull).collect(Collectors.toList());
            //找到需要删除的id
            List<Long> baseTeacherEmployRemoveIds = baseTeacherEmployIds.stream().filter(item -> !baseTeacherEmployOldIds.contains(item)).collect(Collectors.toList());

            for (BaseTeacherEmploy baseTeacherEmploy : xjrUser.getBaseTeacherEmployList()) {
                //如果不等于空则修改
                if (baseTeacherEmploy.getId() != null) {
                    teacherbaseManagerBaseTeacherEmployMapper.updateById(baseTeacherEmploy);
                }
                //如果等于空 则新增
                else {
                    //已经不存在的id 删除
                    baseTeacherEmploy.setUserId(xjrUser.getId());
                    teacherbaseManagerBaseTeacherEmployMapper.insert(baseTeacherEmploy);
                }
            }
            //已经不存在的id 删除
            if(baseTeacherEmployRemoveIds.size() > 0){
                teacherbaseManagerBaseTeacherEmployMapper.deleteBatchIds(baseTeacherEmployRemoveIds);
            }
        }
        //********************************* BaseTeacherEmploy  增删改  结束 *******************************************/

        //********************************* BaseTeacherFamily  增删改  开始 *******************************************/
        {
            // 查出所有子级的id
            List<BaseTeacherFamily> baseTeacherFamilyList = teacherbaseManagerBaseTeacherFamilyMapper.selectList(Wrappers.lambdaQuery(BaseTeacherFamily.class).eq(BaseTeacherFamily::getUserId, xjrUser.getId()).select(BaseTeacherFamily::getId));
            List<Long> baseTeacherFamilyIds = baseTeacherFamilyList.stream().map(BaseTeacherFamily::getId).collect(Collectors.toList());
            //原有子表单 没有被删除的主键
            List<Long> baseTeacherFamilyOldIds = xjrUser.getBaseTeacherFamilyList().stream().map(BaseTeacherFamily::getId).filter(Objects::nonNull).collect(Collectors.toList());
            //找到需要删除的id
            List<Long> baseTeacherFamilyRemoveIds = baseTeacherFamilyIds.stream().filter(item -> !baseTeacherFamilyOldIds.contains(item)).collect(Collectors.toList());

            for (BaseTeacherFamily baseTeacherFamily : xjrUser.getBaseTeacherFamilyList()) {
                //如果不等于空则修改
                if (baseTeacherFamily.getId() != null) {
                    teacherbaseManagerBaseTeacherFamilyMapper.updateById(baseTeacherFamily);
                }
                //如果等于空 则新增
                else {
                    //已经不存在的id 删除
                    baseTeacherFamily.setUserId(xjrUser.getId());
                    teacherbaseManagerBaseTeacherFamilyMapper.insert(baseTeacherFamily);
                }
            }
            //已经不存在的id 删除
            if(baseTeacherFamilyRemoveIds.size() > 0){
                teacherbaseManagerBaseTeacherFamilyMapper.deleteBatchIds(baseTeacherFamilyRemoveIds);
            }
        }
        //********************************* BaseTeacherFamily  增删改  结束 *******************************************/

        //********************************* BaseTeacherFamilyMember  增删改  开始 *******************************************/
        {
            // 查出所有子级的id
            List<BaseTeacherFamilyMember> baseTeacherFamilyMemberList = teacherbaseManagerBaseTeacherFamilyMemberMapper.selectList(Wrappers.lambdaQuery(BaseTeacherFamilyMember.class).eq(BaseTeacherFamilyMember::getUserId, xjrUser.getId()).select(BaseTeacherFamilyMember::getId));
            List<Long> baseTeacherFamilyMemberIds = baseTeacherFamilyMemberList.stream().map(BaseTeacherFamilyMember::getId).collect(Collectors.toList());
            //原有子表单 没有被删除的主键
            List<Long> baseTeacherFamilyMemberOldIds = xjrUser.getBaseTeacherFamilyMemberList().stream().map(BaseTeacherFamilyMember::getId).filter(Objects::nonNull).collect(Collectors.toList());
            //找到需要删除的id
            List<Long> baseTeacherFamilyMemberRemoveIds = baseTeacherFamilyMemberIds.stream().filter(item -> !baseTeacherFamilyMemberOldIds.contains(item)).collect(Collectors.toList());

            for (BaseTeacherFamilyMember baseTeacherFamilyMember : xjrUser.getBaseTeacherFamilyMemberList()) {
                //如果不等于空则修改
                if (baseTeacherFamilyMember.getId() != null) {
                    teacherbaseManagerBaseTeacherFamilyMemberMapper.updateById(baseTeacherFamilyMember);
                }
                //如果等于空 则新增
                else {
                    //已经不存在的id 删除
                    baseTeacherFamilyMember.setUserId(xjrUser.getId());
                    teacherbaseManagerBaseTeacherFamilyMemberMapper.insert(baseTeacherFamilyMember);
                }
            }
            //已经不存在的id 删除
            if(baseTeacherFamilyMemberRemoveIds.size() > 0){
                teacherbaseManagerBaseTeacherFamilyMemberMapper.deleteBatchIds(baseTeacherFamilyMemberRemoveIds);
            }
        }
        //********************************* BaseTeacherFamilyMember  增删改  结束 *******************************************/

        //********************************* BaseTeacherRegular  增删改  开始 *******************************************/
        {
            // 查出所有子级的id
            List<BaseTeacherRegular> baseTeacherRegularList = teacherbaseManagerBaseTeacherRegularMapper.selectList(Wrappers.lambdaQuery(BaseTeacherRegular.class).eq(BaseTeacherRegular::getUserId, xjrUser.getId()).select(BaseTeacherRegular::getId));
            List<Long> baseTeacherRegularIds = baseTeacherRegularList.stream().map(BaseTeacherRegular::getId).collect(Collectors.toList());
            //原有子表单 没有被删除的主键
            List<Long> baseTeacherRegularOldIds = xjrUser.getBaseTeacherRegularList().stream().map(BaseTeacherRegular::getId).filter(Objects::nonNull).collect(Collectors.toList());
            //找到需要删除的id
            List<Long> baseTeacherRegularRemoveIds = baseTeacherRegularIds.stream().filter(item -> !baseTeacherRegularOldIds.contains(item)).collect(Collectors.toList());

            for (BaseTeacherRegular baseTeacherRegular : xjrUser.getBaseTeacherRegularList()) {
                //如果不等于空则修改
                if (baseTeacherRegular.getId() != null) {
                    teacherbaseManagerBaseTeacherRegularMapper.updateById(baseTeacherRegular);
                }
                //如果等于空 则新增
                else {
                    //已经不存在的id 删除
                    baseTeacherRegular.setUserId(xjrUser.getId());
                    teacherbaseManagerBaseTeacherRegularMapper.insert(baseTeacherRegular);
                }
            }
            //已经不存在的id 删除
            if(baseTeacherRegularRemoveIds.size() > 0){
                teacherbaseManagerBaseTeacherRegularMapper.deleteBatchIds(baseTeacherRegularRemoveIds);
            }
        }
        //********************************* BaseTeacherRegular  增删改  结束 *******************************************/

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(List<Long> ids) {
        teacherbaseManagerXjrUserMapper.deleteBatchIds(ids);
        teacherbaseManagerBaseTeacherMapper.delete(Wrappers.lambdaQuery(BaseTeacher.class).in(BaseTeacher::getUserId, ids));
        teacherbaseManagerBaseTeacherContactMapper.delete(Wrappers.lambdaQuery(BaseTeacherContact.class).in(BaseTeacherContact::getUserId, ids));
        teacherbaseManagerBaseTeacherEducationMapper.delete(Wrappers.lambdaQuery(BaseTeacherEducation.class).in(BaseTeacherEducation::getUserId, ids));
        teacherbaseManagerBaseTeacherEmployMapper.delete(Wrappers.lambdaQuery(BaseTeacherEmploy.class).in(BaseTeacherEmploy::getUserId, ids));
        teacherbaseManagerBaseTeacherFamilyMapper.delete(Wrappers.lambdaQuery(BaseTeacherFamily.class).in(BaseTeacherFamily::getUserId, ids));
        teacherbaseManagerBaseTeacherFamilyMemberMapper.delete(Wrappers.lambdaQuery(BaseTeacherFamilyMember.class).in(BaseTeacherFamilyMember::getUserId, ids));
        teacherbaseManagerBaseTeacherRegularMapper.delete(Wrappers.lambdaQuery(BaseTeacherRegular.class).in(BaseTeacherRegular::getUserId, ids));

        return true;
    }
}
