package com.vctgo.system.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vctgo.common.core.text.Convert;
import com.vctgo.common.core.utils.ServletUtils;
import com.vctgo.common.mybatisplus.constant.MybatisPageConstants;
import com.vctgo.common.security.utils.SecurityUtils;
import com.vctgo.system.api.domain.SysClassSetting;
import com.vctgo.system.api.domain.SysUser;
import com.vctgo.system.domain.SysChildhoodManage;
import com.vctgo.system.domain.SysReClassUser;
import com.vctgo.system.domain.dto.BindClassUserDto;
import com.vctgo.system.mapper.SysChildhoodManageMapper;
import com.vctgo.system.mapper.SysClassSettingMapper;
import com.vctgo.system.mapper.SysReClassUserMapper;
import com.vctgo.system.service.ISysReClassUserService;
import com.vctgo.system.util.ConstantUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 班级配置人员信息Service业务层处理
 *
 * @author wanglonghua
 * @date 2023-10-09
 */
@Slf4j
@Service
public class SysReClassUserServiceImpl implements ISysReClassUserService
{
    @Autowired
    private SysReClassUserMapper sysReClassUserMapper;

    @Autowired
    private SysChildhoodManageMapper sysChildhoodManageMapper;

    @Autowired
    private SysClassSettingMapper sysClassSettingMapper;

    /**
     * 查询班级配置人员信息
     *
     * @param id 班级配置人员信息主键
     * @return 班级配置人员信息
     */
    @Override
    public SysReClassUser selectSysReClassUserById(Long id)
    {
        return sysReClassUserMapper.selectById(id);
    }

    /**
     * 查询班级配置人员信息列表-分页
     *
     * @param sysReClassUser 班级配置人员信息
     * @return 班级配置人员信息
     */
    @Override
    public IPage<SysReClassUser> selectSysReClassUserPage(SysReClassUser sysReClassUser)
    {
        Page mpPage =new Page(Convert.toLong(ServletUtils.getParameterToInt(MybatisPageConstants.PAGE_NUM),1L)
                ,Convert.toLong(ServletUtils.getParameterToInt(MybatisPageConstants.PAGE_SIZE),10L));
        return sysReClassUserMapper.selectSysReClassUserList(mpPage,sysReClassUser);
    }

    /**
     * 查询班级配置人员信息列表
     *
     * @param sysReClassUser 班级配置人员信息
     * @return 班级配置人员信息
     */
    @Override
    public List<SysReClassUser> selectSysReClassUserList(SysReClassUser sysReClassUser)
    {
        return sysReClassUserMapper.selectSysReClassUserList(sysReClassUser);
    }

    /**
     * 通过班级id统计绑定的用户数
     *
     * @param classId 班级id
     * @return 班级配置人员总数
     */
    @Override
    public Long staticsBindUserCountByClassId(Long classId, String bindUserPosition)
    {
        return sysReClassUserMapper.staticsBindUserCountByClassId(classId, bindUserPosition);
    }

    @Override
    public BindClassUserDto getClassAllocationDetail(BindClassUserDto bindClassUserDto) {
        LambdaQueryWrapper<SysReClassUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysReClassUser::getClassId, bindClassUserDto.getClassId());
        queryWrapper.eq(bindClassUserDto.getBindType() != null, SysReClassUser::getBindUserPosition, bindClassUserDto.getBindType());
        queryWrapper.eq(SysReClassUser::getIsDeleted, ConstantUtils.IS_DELETED_0);
        List<SysReClassUser> sysReClassUserList = sysReClassUserMapper.selectList(queryWrapper);
        BindClassUserDto bindClassUserDtox = new BindClassUserDto();
        bindClassUserDtox.setClassId(bindClassUserDto.getClassId());
        bindClassUserDtox.setMainTeacherList(new ArrayList<>());
        bindClassUserDtox.setAssistantTeacherList(new ArrayList<>());
        bindClassUserDtox.setNurseTeacherList(new ArrayList<>());
        bindClassUserDtox.setChildhoodList(new ArrayList<>());
        sysReClassUserList.forEach(obj->{
            SysUser sysUser = new SysUser();
            sysUser.setUserId(obj.getBindUserId());
            sysUser.setNickName(obj.getBindUserName());
            sysUser.setDelFlag(ConstantUtils.IS_DELETED_0);
            sysUser.setTenantId(obj.getTenantId());
            bindClassUserDtox.setBindType(Integer.valueOf(obj.getBindUserPosition()));
            if("1".equals(obj.getBindUserPosition())){
                bindClassUserDtox.getMainTeacherList().add(sysUser);
            }else if("2".equals(obj.getBindUserPosition())){
                bindClassUserDtox.getAssistantTeacherList().add(sysUser);
            }else if("3".equals(obj.getBindUserPosition())){
                bindClassUserDtox.getNurseTeacherList().add(sysUser);
            }else if("4".equals(obj.getBindUserPosition())){
                bindClassUserDtox.getChildhoodList().add(sysUser);
            }
        });
        return bindClassUserDtox;
    }

    /**
     * 新增班级配置人员信息
     *
     * @param bindClassUserDto 班级配置人员信息
     * @return 结果
     */
    @Override
    public int allocationSysReClassUser(BindClassUserDto bindClassUserDto)
    {
        //不管之前有没有绑定人员，先统一将之前绑定的数据重置为删除状态，重新绑定
        logicalDeleteSysReClassUserByClassId(bindClassUserDto.getClassId(), bindClassUserDto.getBindType());
        List<SysReClassUser> sysReClassUserList = new ArrayList<>();
        if(bindClassUserDto.getBindType() == 1){
            sysReClassUserList = transformAllocationTeacherList(bindClassUserDto);
            return unbindTeacher(bindClassUserDto, sysReClassUserList);
        }else if(bindClassUserDto.getBindType() == 4){
            sysReClassUserList = transformAllocationChildList(bindClassUserDto);
            return unbindChildhood(bindClassUserDto, sysReClassUserList);
        }
        return sysReClassUserList.size();
    }

    @Override
    public List<SysClassSetting> getPointUserClassList(Long userId, Integer bindUserPosition) {
        LambdaQueryWrapper<SysReClassUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SysReClassUser::getBindUserId, userId)
               .eq(SysReClassUser::getTenantId, SecurityUtils.getTenantId())
               .eq(SysReClassUser::getIsDeleted, ConstantUtils.IS_DELETED_0);
        if(bindUserPosition == 5){
            List<String> userPositionList = Stream.of("1", "2", "3").collect(Collectors.toList());
            wrapper.in(SysReClassUser::getBindUserPosition, userPositionList);
        }else if(bindUserPosition == 12){
            List<String> userPositionList = Stream.of("1", "2").collect(Collectors.toList());
            wrapper.in(SysReClassUser::getBindUserPosition, userPositionList);
        }else{
            wrapper.eq(SysReClassUser::getBindUserPosition, bindUserPosition);
        }
        List<SysReClassUser> sysReClassUserList = sysReClassUserMapper.selectList(wrapper);
        List<Long> classIdList = sysReClassUserList.stream().map(SysReClassUser::getClassId).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(classIdList)){
            return Collections.EMPTY_LIST;
        }
        LambdaQueryWrapper<SysClassSetting> classWrapper = Wrappers.lambdaQuery();
        classWrapper.in(CollectionUtils.isNotEmpty(classIdList), SysClassSetting::getId, classIdList)
                    .eq(SysClassSetting::getTenantId, SecurityUtils.getTenantId())
                    .eq(SysClassSetting::getIsDeleted, ConstantUtils.IS_DELETED_0)
                    .orderByDesc(SysClassSetting::getEnrollmentYear)
                    .orderByAsc(SysClassSetting::getGradeIn)
                    .orderByAsc(SysClassSetting::getClassNumber);
        return sysClassSettingMapper.selectList(classWrapper);
    }

    public int unbindTeacher(BindClassUserDto bindClassUserDto, List<SysReClassUser> sysReClassUserList){
        sysReClassUserMapper.insertBatch(sysReClassUserList);
        ThreadUtil.execAsync(() -> {
            //根据班级id彻底删除之前绑定的人员数据，防止每次全量插入撑爆数据表
            deleteSysReClassUserByClassId(bindClassUserDto.getClassId(), bindClassUserDto.getBindType());
        });
        return sysReClassUserList.size();
    }

    public int unbindChildhood(BindClassUserDto bindClassUserDto, List<SysReClassUser> sysReClassUserList){
        sysReClassUserMapper.insertBatch(sysReClassUserList);
        //重置该班级的幼儿状态（可能解绑了一部分幼儿，又新增了一部分幼儿）
        sysChildhoodManageMapper.resetClassChildhoodInfo(bindClassUserDto.getClassId());
        if(CollectionUtils.isNotEmpty(sysReClassUserList)){
            //批量更新幼儿班级信息
            List<Long> childhoodIdList = sysReClassUserList.stream().map(SysReClassUser::getBindUserId).collect(Collectors.toList());
            LambdaUpdateWrapper<SysChildhoodManage> updateWrapper = Wrappers.lambdaUpdate();
            updateWrapper.set(SysChildhoodManage::getClassId, bindClassUserDto.getClassId())
                    .set(SysChildhoodManage::getInKindergartenStatus, ConstantUtils.IN_KINDERGARTEN_STATUS_0)
                    .eq(SysChildhoodManage::getIsDeleted, ConstantUtils.IS_DELETED_0)
                    .in(SysChildhoodManage::getId,childhoodIdList);
            sysChildhoodManageMapper.update(new SysChildhoodManage(), updateWrapper);
        }
        ThreadUtil.execAsync(() -> {
            //根据班级id彻底删除之前绑定的人员数据，防止每次全量插入撑爆数据表
            deleteSysReClassUserByClassId(bindClassUserDto.getClassId(), bindClassUserDto.getBindType());
        });
        return sysReClassUserList.size();
    }

    public List<SysReClassUser> transformAllocationTeacherList(BindClassUserDto bindClassUserDto){
        List<SysReClassUser> allocationTeacherList = new ArrayList<>();
        List<SysReClassUser> mainTeacherList =
                bindClassUserDto.getMainTeacherList().stream().map(obj->{
                    SysReClassUser sysReClassUser = new SysReClassUser();
                    sysReClassUser.setClassId(bindClassUserDto.getClassId());
                    sysReClassUser.setBindUserId(obj.getUserId());
                    sysReClassUser.setBindUserName(obj.getNickName());
                    sysReClassUser.setBindUserPosition("1");
                    return sysReClassUser;
                }).collect(Collectors.toList());
        List<SysReClassUser> assistantTeacherList =
                bindClassUserDto.getAssistantTeacherList().stream().map(obj->{
                    SysReClassUser sysReClassUser = new SysReClassUser();
                    sysReClassUser.setClassId(bindClassUserDto.getClassId());
                    sysReClassUser.setBindUserId(obj.getUserId());
                    sysReClassUser.setBindUserName(obj.getNickName());
                    sysReClassUser.setBindUserPosition("2");
                    return sysReClassUser;
                }).collect(Collectors.toList());
        List<SysReClassUser> nurseTeacherList =
                bindClassUserDto.getNurseTeacherList().stream().map(obj->{
                    SysReClassUser sysReClassUser = new SysReClassUser();
                    sysReClassUser.setClassId(bindClassUserDto.getClassId());
                    sysReClassUser.setBindUserId(obj.getUserId());
                    sysReClassUser.setBindUserName(obj.getNickName());
                    sysReClassUser.setBindUserPosition("3");
                    return sysReClassUser;
                }).collect(Collectors.toList());
        allocationTeacherList.addAll(mainTeacherList);
        allocationTeacherList.addAll(assistantTeacherList);
        allocationTeacherList.addAll(nurseTeacherList);
        return allocationTeacherList;
    }

    public List<SysReClassUser> transformAllocationChildList(BindClassUserDto bindClassUserDto){
        return bindClassUserDto.getChildhoodList().stream().map(obj->{
                SysReClassUser sysReClassUser = new SysReClassUser();
                sysReClassUser.setClassId(bindClassUserDto.getClassId());
                sysReClassUser.setBindUserId(obj.getUserId());
                sysReClassUser.setBindUserName(obj.getNickName());
                sysReClassUser.setBindUserPosition("4");
                return sysReClassUser;
        }).collect(Collectors.toList());
    }

    /**
     * 修改班级配置人员信息
     *
     * @param sysReClassUser 班级配置人员信息
     * @return 结果
     */
    @Override
    public int updateSysReClassUser(SysReClassUser sysReClassUser)
    {
        return sysReClassUserMapper.updateById(sysReClassUser);
    }

    /**
     * 逻辑删除班级配置人员信息
     *
     * @param ids 需要删除的班级配置人员信息主键
     * @return 结果
     */
    @Override
    public int logicalDeleteSysReClassUserByIds(Long[] ids)
    {
        SysReClassUser sysReClassUser = new SysReClassUser();
        sysReClassUser.setUpdateById(SecurityUtils.getUserId());
        sysReClassUser.setUpdateBy(SecurityUtils.getUsername());
        sysReClassUser.setUpdateTime(new Date());
        sysReClassUser.setIsDeleted(ConstantUtils.IS_DELETED_1);
        return sysReClassUserMapper.logicalDeleteSysReClassUserByIds(ids, sysReClassUser);
    }

    /**
     * 逻辑删除班级配置人员信息
     *
     * @param classId 需要删除的班级配置人员信息主键
     * @return 结果
     */
    public int logicalDeleteSysReClassUserByClassId(Long classId, Integer bindType)
    {
        return sysReClassUserMapper.logicalDeleteSysReClassUserByClassId(classId, bindType);
    }

    /**
     * 批量删除班级配置人员信息
     *
     * @param ids 需要删除的班级配置人员信息主键
     * @return 结果
     */
    @Override
    public int deleteSysReClassUserByIds(Long[] ids)
    {
        return sysReClassUserMapper.deleteSysReClassUserByIds(ids);
    }

    /**
     * 批量删除班级配置人员信息
     *
     * @param classId 需要删除的班级配置人员信息主键
     * @return 结果
     */
    public int deleteSysReClassUserByClassId(Long classId, Integer bindType)
    {
        return sysReClassUserMapper.deleteSysReClassUserByClassId(classId, bindType);
    }

    /**
     * 删除班级配置人员信息信息
     *
     * @param id 班级配置人员信息主键
     * @return 结果
     */
    @Override
    public int deleteSysReClassUserById(Long id)
    {
        return sysReClassUserMapper.deleteById(id);
    }
}
