package com.yonge.cooleshow.biz.dal.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.microsvc.toolkit.middleware.rtc.enums.EDeviceMessageType;
import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
import com.yonge.cooleshow.auth.api.entity.SysUser;
import com.yonge.cooleshow.auth.config.CustomerServiceConfig;
import com.yonge.cooleshow.biz.dal.dao.EmployeeDao;
import com.yonge.cooleshow.biz.dal.dao.StudentStarDao;
import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
import com.yonge.cooleshow.biz.dal.dto.TeacherDto;
import com.yonge.cooleshow.biz.dal.dto.req.TeacherSubmitReq;
import com.yonge.cooleshow.biz.dal.dto.search.TeacherSearch;
import com.yonge.cooleshow.biz.dal.entity.*;
import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
import com.yonge.cooleshow.biz.dal.enums.ImGroupType;
import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
import com.yonge.cooleshow.biz.dal.enums.TeacherTagEnum;
import com.yonge.cooleshow.biz.dal.enums.TeacherTypeEnum;
import com.yonge.cooleshow.biz.dal.mapper.TenantGroupMapper;
import com.yonge.cooleshow.biz.dal.mapper.UserTenantBindRecordMapper;
import com.yonge.cooleshow.biz.dal.queryInfo.TeacherQueryInfo;
import com.yonge.cooleshow.biz.dal.service.ImGroupService;
import com.yonge.cooleshow.biz.dal.service.StudentService;
import com.yonge.cooleshow.biz.dal.service.StudentStarService;
import com.yonge.cooleshow.biz.dal.service.SubjectService;
import com.yonge.cooleshow.biz.dal.service.SysConfigService;
import com.yonge.cooleshow.biz.dal.service.SysMessageService;
import com.yonge.cooleshow.biz.dal.service.TeacherAuthEntryRecordService;
import com.yonge.cooleshow.biz.dal.service.TeacherAuthMusicianRecordService;
import com.yonge.cooleshow.biz.dal.service.TeacherService;
import com.yonge.cooleshow.biz.dal.service.TeacherStyleVideoService;
import com.yonge.cooleshow.biz.dal.service.TeacherTotalService;
import com.yonge.cooleshow.biz.dal.service.UserAccountService;
import com.yonge.cooleshow.biz.dal.service.UserFirstTimeService;
import com.yonge.cooleshow.biz.dal.service.im.ImGroupCoreService;
import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumRefMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantUnbindHistoryMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantUnbindRecordMapper;
import com.yonge.cooleshow.biz.dal.queryInfo.TeacherQueryInfo;
import com.yonge.cooleshow.biz.dal.service.*;
import com.yonge.cooleshow.biz.dal.vo.HotTeacherVo;
import com.yonge.cooleshow.biz.dal.vo.MusicSheetUploadCountVo;
import com.yonge.cooleshow.biz.dal.vo.MyFens;
import com.yonge.cooleshow.biz.dal.vo.TeacherAuthEntryRecordVo;
import com.yonge.cooleshow.biz.dal.vo.TeacherHomeVo;
import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
import com.yonge.cooleshow.biz.dal.wordfilter.WordFilter;
import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
import com.yonge.cooleshow.common.constant.SysConfigConstant;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.cooleshow.common.enums.CacheNameEnum;
import com.yonge.cooleshow.common.enums.ESettlementFrom;
import com.yonge.cooleshow.common.enums.ETenantUnBindAuditStatus;
import com.yonge.cooleshow.common.enums.UserFirstTimeTypeEnum;
import com.yonge.cooleshow.common.enums.YesOrNoEnum;
import com.yonge.toolset.base.exception.BizException;
import com.yonge.toolset.base.util.StringUtil;
import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
import com.yonge.toolset.thirdparty.user.realname.RealnameAuthenticationPlugin;
import com.yonge.toolset.utils.date.DateUtil;
import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
import com.yonge.toolset.utils.string.ValueUtil;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.yonge.cooleshow.biz.dal.constant.LiveRoomConstant.TEACHER_TEMP_LIVE_ROOM;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.yonge.cooleshow.biz.dal.constant.LiveRoomConstant.TEACHER_TEMP_LIVE_ROOM;

@Service
public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> implements TeacherService {

    private final static Logger log = LoggerFactory.getLogger(TeacherServiceImpl.class);

    @Autowired
    private TeacherStyleVideoService teacherStyleVideoService;
    @Resource
    private SysUserFeignService userFeignService;
    @Autowired
    private TeacherAuthEntryRecordService entryRecordService;
    @Autowired
    private TeacherAuthMusicianRecordService musicianRecordService;
    @Resource
    private EmployeeDao employeeDao;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private WordFilter wordFilter;
    @Autowired
    private StudentStarService studentStarService;
    @Autowired
    private UserAccountService userAccountService;
    @Autowired
    private UserFirstTimeService userFirstTimeService;
    @Autowired
    private TeacherTotalService totalService;

    @Autowired
    private SubjectService subjectService;

    @Autowired
    private StudentStarDao studentStarDao;

    @Autowired
    private StudentService studentService;

    @Autowired
    private SysMessageService sysMessageService;

    @Autowired
    private ImGroupService imGroupService;

    @Autowired
    private ImGroupCoreService imGroupCoreService;

    @Autowired
    private TenantInfoService tenantInfoService;

    @Autowired
    private ImGroupMemberService imGroupMemberService;

    @Autowired
    private ImUserFriendService imUserFriendService;

    @Autowired
    private MusicSheetService musicSheetService;

    @Autowired
    private TenantUnbindRecordMapper tenantUnbindRecordMapper;

    @Autowired
    private TenantUnbindHistoryMapper tenantUnbindHistoryMapper;

    @Autowired
    private TenantAlbumMapper tenantAlbumMapper;

    @Autowired
    private TenantAlbumRefMapper tenantAlbumRefMapper;

    @Autowired
    private SmsCodeService smsCodeService;

    @Autowired
    private RealnameAuthenticationPlugin realnameAuthenticationPlugin;

    @Autowired
    private CustomerServiceConfig customerServiceConfig;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private TenantGroupMapper tenantGroupMapper;

    @Autowired
    private UserTenantBindRecordMapper userTenantBindRecordMapper;


    @Override
    public TeacherDao getDao() {
        return baseMapper;
    }

    @Override
    public TeacherVo detail(Long userId) {
        TeacherVo detail = baseMapper.detail(userId);
        if (null == detail) {
            detail = new TeacherVo();
        }
        int num = DateUtil.daysBetween(new Date(), detail.getMembershipEndTime());
        detail.setMembershipDays(Math.max(num, 0));
        List<TeacherStyleVideo> teacherStyleVideos = teacherStyleVideoService.selectListByUserId(userId);
        detail.setStyleVideo(teacherStyleVideos);
        TeacherAuthEntryRecordVo lastRecordByUserId = entryRecordService.getLastRecordByUserId(userId);
        if (null != lastRecordByUserId) {
            detail.setVerifyUser(lastRecordByUserId.getVerifyUser());
        }
        String teacherType = TeacherTypeEnum.getTeacherType(detail.getEntryFlag(), detail.getMusicianFlag());
        detail.setTeacherType(teacherType);
        Long tenantId = detail.getTenantId();
        if (tenantId != null) {
            if (tenantId == -1) {
                detail.setTenantName("平台老师");
            } else {
                TenantInfo tenantInfo = tenantInfoService.detail(tenantId);
                detail.setTenantName(tenantInfo == null ? "" : tenantInfo.getName());
            }
        }
        return detail;
    }

    @Override
    public IPage<TeacherVo> selectPage(IPage<TeacherVo> page, TeacherSearch search) {
        List<TeacherVo> teacherVos = baseMapper.selectPage(page, search);

        if (CollectionUtils.isEmpty(teacherVos)) {
            return page.setRecords(teacherVos);
        }
        //设置声部
        List<Long> subjectIds =
                teacherVos.stream().filter(o -> o.getSubjectId() != null).flatMap(o -> Arrays.stream(o.getSubjectId().split(","))).map(Long::parseLong).collect(Collectors.toList());
        List<Subject> subjects = subjectService.findBySubjectByIdList(subjectIds);

        Map<Long, String> subjectMap = subjects.stream().collect(Collectors.toMap(Subject::getId, Subject::getName));

        List<Long> userIds = teacherVos.stream().map(Teacher::getUserId).distinct().collect(Collectors.toList());

        List<MusicSheet> musicSheets = musicSheetService.lambdaQuery()
                .in(MusicSheet::getUserId, userIds)
                .eq(MusicSheet::getDelFlag, false)
                .eq(MusicSheet::getState, 1)
                .eq(MusicSheet::getSourceType, "TEACHER").list();

        Map<Long, List<MusicSheet>> groupByUserId = musicSheets.stream().collect(Collectors.groupingBy(MusicSheet::getUserId));

        // 添加小组信息
        Map<Long, List<TenantGroup>> groupByAdminId = new HashMap<>();
        List<Long> teacherIds = teacherVos.stream().map(Teacher::getUserId).distinct().collect(Collectors.toList());
        if(!teacherIds.isEmpty()){
            QueryWrapper<TenantGroup> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(TenantGroup::getAdminId,teacherIds);
            List<TenantGroup> tenantGroups = tenantGroupMapper.selectList(queryWrapper);
            Map<Long, List<TenantGroup>> groupBy = tenantGroups.stream().collect(Collectors.groupingBy(TenantGroup::getAdminId));
            groupByAdminId.putAll(groupBy);
        }


        for (TeacherVo teacherVo : teacherVos) {
            List<String> groups = groupByAdminId.getOrDefault(teacherVo.getUserId(), new ArrayList<>())
                    .stream().map(TenantGroup::getName).collect(Collectors.toList());
            teacherVo.setTenantGroupName(String.join(",", groups));

            List<MusicSheet> musicSheetList = groupByUserId.getOrDefault(teacherVo.getUserId(), new ArrayList<>());
            teacherVo.setMusicSheetCount(musicSheetList.size());
            List<String> names = musicSheetList.stream().map(MusicSheet::getMusicSheetName).collect(Collectors.toList());
            teacherVo.setMusicSheetName(String.join(",", names));
            if (null == teacherVo.getSubjectId()) {
                continue;
            }

            String subjectNames = Arrays.stream(teacherVo.getSubjectId().split(",")).map(Long::parseLong).map(o -> {
                String subjectName = subjectMap.get(o);
                if (!StringUtil.isEmpty(subjectName)) {
                    return subjectName;
                }
                return null;
            }).filter(Objects::nonNull).collect(Collectors.joining(","));
            teacherVo.setSubjectName(subjectNames);
        }
        return page.setRecords(teacherVos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public HttpResponseResult<Boolean> submit(TeacherSubmitReq teacherSubmitReq) throws BizException {
        if (null == teacherSubmitReq.getUserId()) {

            if (StringUtils.isNoneBlank(teacherSubmitReq.getPhone(), teacherSubmitReq.getCode())) {
                // 验证手机验证码是否正确
                if (!smsCodeService.verifyValidCode(teacherSubmitReq.getPhone(), teacherSubmitReq.getCode(),
                        "REGISTER")) {
                    throw new BizException("验证码错误");
                }
            }
            //创建
            return doCreate(teacherSubmitReq);
        } else {
            //修改
            return doUpdate(teacherSubmitReq);
        }
    }

    @Override
    public HttpResponseResult<TeacherHomeVo> queryUserInfo(Long userId) {
        TeacherVo teacher = detail(userId);
        if (null == teacher) {
            return HttpResponseResult.failed("未查询到老师信息");
        }
        TeacherHomeVo teacherHomeVo = new TeacherHomeVo();
        BeanUtils.copyProperties(teacher, teacherHomeVo);

        try {
            ImGroupWrapper.ImUserInfo register = imGroupCoreService.register(teacher.getUserId().toString(),
                    ClientEnum.TEACHER.getCode(),
                    teacher.getUsername(),
                    teacher.getAvatar());
            teacherHomeVo.setImToken(register.getImToken());
        } catch (Exception e) {
            throw new BizException("获取IMToken失败");
        }

        // 设置IM用户ID
        teacherHomeVo.setImUserId(imGroupService.getImUserId(userId.toString(),ClientEnum.TEACHER.getCode()));

        teacherHomeVo.setDegreeDate(teacher.getDegreeDate());
        teacherHomeVo.setTeacherDate(teacher.getTeacherDate());
        //身份证号、手机号脱敏
        teacherHomeVo.setIdCardNo(ValueUtil.fuzzyIdCard(teacherHomeVo.getIdCardNo()));
//        teacherHomeVo.setPhone(ValueUtil.fuzzyMobile(teacherHomeVo.getPhone()));
        teacherHomeVo.setHeardUrl(teacher.getAvatar());
        teacherHomeVo.setIsVip(teacher.getIsVip());
        int num = DateUtil.daysBetween(new Date(), teacher.getMembershipEndTime());
        teacherHomeVo.setMembershipDays(Math.max(num, 0));
        if (YesOrNoEnum.YES.equals(teacher.getEntryFlag())) {
            teacherHomeVo.setEntryStatus(AuthStatusEnum.PASS);
        } else {
            TeacherAuthEntryRecordVo entryRecord = entryRecordService.getLastRecordByUserId(userId);
            if (null == entryRecord) {
                teacherHomeVo.setEntryStatus(AuthStatusEnum.UNPAALY);
            } else {
                teacherHomeVo.setEntryStatus(entryRecord.getTeacherAuthStatus());
            }
        }
        // 设置默认查询声部名称
        if (teacher.getDefaultSubject() != null) {
            Subject subject = subjectService.get(teacher.getDefaultSubject());
            if (subject != null) {
                teacherHomeVo.setDefaultSubjectName(subject.getName());
            }
        }

        if (YesOrNoEnum.YES.equals(teacher.getMusicianFlag())) {
            teacherHomeVo.setMusicianAuthStatus(AuthStatusEnum.PASS);
        } else {
            TeacherAuthMusicianRecord musicianRecord = musicianRecordService.getLastRecordByUserId(userId);
            if (null == musicianRecord) {
                teacherHomeVo.setMusicianAuthStatus(AuthStatusEnum.UNPAALY);
            } else {
                teacherHomeVo.setMusicianAuthStatus(musicianRecord.getTeacherAuthStatus());
            }
        }

        TeacherTotal total = totalService.getTotalById(userId);

        if (null == total) {
            total = new TeacherTotal();
        }
        teacherHomeVo.setStarGrade(null == total.getStarGrade() ? 0 : total.getStarGrade().intValue());
        teacherHomeVo.setFansNum(null == total.getFansNum() ? 0 : total.getFansNum());
        teacherHomeVo.setExpTime(null == total.getExpTime() ? 0 : total.getExpTime());
        teacherHomeVo.setUnExpTime(null == total.getUnExpTime() ? 0 : total.getUnExpTime());
        teacherHomeVo.setMusicAlbumNum(null == total.getMusicAlbumNum() ? 0 : total.getMusicAlbumNum());
        teacherHomeVo.setMusicSheetNum(null == total.getMusicSheetNum() ? 0 : total.getMusicSheetNum());

        // 老师所属机构信息
        teacherHomeVo.setTenantAlbumStatus(0);
        TenantInfo tenantInfo = tenantInfoService.detail(teacher.getTenantId());
        if (tenantInfo != null) {
            teacherHomeVo.setTenantName(tenantInfo.getName());
            List<Long> tenantAlbumIds = tenantAlbumRefMapper.selectList(Wrappers.<TenantAlbumRef>lambdaQuery()
                            .eq(TenantAlbumRef::getTenantId, tenantInfo.getId())).stream()
                    .map(TenantAlbumRef::getTenantAlbumId).collect(Collectors.toList());
            if (!tenantAlbumIds.isEmpty()) {
                List<TenantAlbum> tenantAlbums = tenantAlbumMapper.selectList(Wrappers.<TenantAlbum>lambdaQuery()
                        .in(TenantAlbum::getId, tenantAlbumIds)
                        .eq(TenantAlbum::getDelFlag, false).eq(TenantAlbum::getStatus, true));
                if (!tenantAlbums.isEmpty()) {
                    teacherHomeVo.setTenantAlbumStatus(2);
                    teacherHomeVo.setTenantAlbumFlag(YesOrNoEnum.YES);
                }
            }
        }

        // 老师学生人数统计
        List<Long> teacherIds = Lists.newArrayList(userId);
        Map<Long, Integer> studentNumsMap = getBaseMapper().selectTeacherStudentNumberStatInfo(teacherIds).stream()
                .collect(Collectors.toMap(StatGroupWrapper::getId, StatGroupWrapper::getTotal, (o, n) -> n));

        teacherHomeVo.setStudentNums(studentNumsMap.getOrDefault(userId, 0));

        //取直播缓存
        RMap<Long, String> liveMap = redissonClient.getMap(TEACHER_TEMP_LIVE_ROOM);
        String roomUid = liveMap.get(userId);
        if (!StringUtil.isEmpty(roomUid)) {
            teacherHomeVo.setLiveing(YesOrNoEnum.YES);
            teacherHomeVo.setRoomUid(roomUid);
        } else {
            teacherHomeVo.setLiveing(YesOrNoEnum.NO);
        }
        return HttpResponseResult.succeed(teacherHomeVo);
    }

    @Override
    public HttpResponseResult<Boolean> openLive(Long id) {
        TeacherTotal teacherTotal =
                (TeacherTotal) redissonClient.getBucket(CacheNameEnum.TEACHER_TOTAL.getRedisKey(id)).get();
        if (null == teacherTotal) {
            teacherTotal = new TeacherTotal();
        }

        //开通直播需要粉丝数
        Integer fansNum =
                Integer.parseInt(sysConfigService.findByParamName(SysConfigConstant.OPEN_LIVE_FANS_NUM).getParamValue());
        //开通直播需要已完成课时数
        Integer overClass =
                Integer.parseInt(sysConfigService.findByParamName(SysConfigConstant.OPEN_LIVE_OVER_CLASS).getParamValue());
        //根据老师规则，判断老师直播权限
        if (teacherTotal.getFansNum() >= fansNum && teacherTotal.getExpTime() >= overClass) {
            Teacher teacher = new Teacher();
            teacher.setUserId(id);
            teacher.setLiveFlag(YesOrNoEnum.YES);
            teacher.setLiveDate(new Date());
            teacher.setUpdateTime(new Date());
            baseMapper.updateById(teacher);

            // 添加标签
            this.setTeacherTag(id, TeacherTagEnum.LIVE);

            //记录首次开通直播时间
            userFirstTimeService.recordTime(id, ClientEnum.TEACHER, UserFirstTimeTypeEnum.LIVEING);
            return HttpResponseResult.status(true);
        } else {
            return HttpResponseResult.failed("不满足开通条件");
        }
    }

    @Override
    public List<Subject> querySubject(Long userId) {
        List<Subject> subjects = baseMapper.querySubject(userId);
        return subjects;
    }


    private HttpResponseResult<Boolean> doCreate(TeacherSubmitReq teacherSubmitReq) throws BizException {
        //更新sys_user
        SysUser sysUser = employeeDao.querySysUserByPhone(teacherSubmitReq.getPhone());
        if (null == sysUser) {
            //设置默认头像
            if (StringUtil.isEmpty(teacherSubmitReq.getAvatar())) {
                String defaultHeard = sysConfigService.findConfigValue(SysConfigConstant.TEACHER_AVATAR);
                teacherSubmitReq.setAvatar(defaultHeard);
            }
            sysUser = insertSysUser(teacherSubmitReq);
            teacherSubmitReq.setUserId(sysUser.getId());
        } else {
            String userType = sysUser.getUserType();
            List<String> userTypes = Arrays.stream(userType.split(",")).collect(Collectors.toList());
            if (userTypes.contains(ClientEnum.TEACHER.getCode())) {
                Teacher teacher = this.getById(sysUser.getId());
                // 机构邀请平台老师注册
                if(Optional.ofNullable(teacher.getTenantId()).orElse(-1L) == -1 && Optional.ofNullable(teacherSubmitReq.getTenantId()).orElse(-1L)>-1){
                    teacherSubmitReq.setSettlementFrom(ESettlementFrom.TENANT);
                }else {
                    throw new BizException("该手机号已经注册老师账号");
                }
            }
            teacherSubmitReq.setUserId(sysUser.getId());
            updateSysUser(teacherSubmitReq);
        }
        //新增修改老师表
        Teacher teacher = insertOrUpdateTeacher(teacherSubmitReq);

        // 机构老师与学生互加好友关系
        if (Optional.ofNullable(teacher.getTenantId()).orElse(-1L) > 0) {
            // 自动与机构学生成为好友
            Set<Long> collect = studentService.lambdaQuery()
                    .eq(Student::getTenantId, teacher.getTenantId()).list().stream()
                    .map(Student::getUserId).collect(Collectors.toSet());

            imUserFriendService.saveUserFriend(teacher.getUserId(), collect);

        }

        return HttpResponseResult.succeed(true);
    }

    private HttpResponseResult<Boolean> doUpdate(TeacherSubmitReq teacherSubmitReq) {
        //更新sys_user
        updateSysUser(teacherSubmitReq);
        //新增修改老师表
        insertOrUpdateTeacher(teacherSubmitReq);
        return HttpResponseResult.succeed(true);
    }

    private SysUser insertSysUser(TeacherSubmitReq teacherSubmitReq) {
        SysUser sysUser = new SysUser();
        sysUser = getUserDetil(sysUser, teacherSubmitReq);
        //初始密码，klx+手机号四位
        String password = "klx" + sysUser.getPhone().substring(sysUser.getPhone().length() - 4);
        sysUser.setPassword(new BCryptPasswordEncoder().encode(password));
        //插入
        int num = employeeDao.insertSysUser(sysUser);
        if (num <= 0) {
            throw new BizException("插入用户信息失败");
        }
        //设置昵称
        if (StringUtils.isEmpty(sysUser.getUsername())) {
            sysUser.setUsername("游客" + sysUser.getId());
        }
        employeeDao.updateSysUser(sysUser);
        return sysUser;
    }

    private SysUser updateSysUser(TeacherSubmitReq teacherSubmitReq) {
        //判断手机号
        SysUser sysUser = employeeDao.querySysUserByPhone(teacherSubmitReq.getPhone());
        if (null != sysUser && !teacherSubmitReq.getUserId().equals(sysUser.getId())) {
            throw new BizException("该手机号已经被注册");
        }
        sysUser = employeeDao.querySysUserById(teacherSubmitReq.getUserId());
        if (null == sysUser) {
            throw new BizException("未找到用户");
        }
        sysUser = getUserDetil(sysUser, teacherSubmitReq);
        sysUser.setUpdateTime(new Date());
        employeeDao.updateSysUser(sysUser);
        return sysUser;
    }

    private Teacher insertOrUpdateTeacher(TeacherSubmitReq teacherSubmitReq) {
        if(ESettlementFrom.NO.equals(teacherSubmitReq.getSettlementFrom())){
            teacherSubmitReq.setIsSettlement(false);
        }else {
            teacherSubmitReq.setIsSettlement(true);
        }
        Teacher teacher = baseMapper.selectById(teacherSubmitReq.getUserId());
        if (null == teacher) {
            teacher = new Teacher();
            teacher.setUserId(teacherSubmitReq.getUserId());
            teacher = getTeacherDetil(teacher, teacherSubmitReq);
            baseMapper.insert(teacher);

            // 导入IM账号到三方
            try {
                imGroupCoreService.register(String.valueOf(teacher.getUserId()), ClientEnum.TEACHER.getCode(),
                        teacherSubmitReq.getUsername(), teacher.getAvatar());
            } catch (Exception e) {
                log.error("导入IM账号到三方 teacherId={}", teacher.getUserId(), e);
            }

            //插入老师账户表
            UserAccount oldAcc = userAccountService.getById(teacherSubmitReq.getUserId());
            if (null == oldAcc) {
                UserAccount userAccount = new UserAccount();
                userAccount.setUserId(teacherSubmitReq.getUserId());
                userAccountService.save(userAccount);
            }
            // 机构老师添加机构绑定记录
            addBindUnBindRecord(teacher.getUserId(),teacher.getTenantId(),true);
            sendBindUnBindSMS(teacher.getUserId(), teacherSubmitReq.getPhone(), MessageTypeEnum.TEACHER_BIND_TENANT, teacher.getTenantId());

            //  与客服建立好友
            String customerService = customerServiceConfig.getCustomerService();
            if (StringUtils.isNotBlank(customerService)) {
                List<String> phones = Arrays.stream(customerService.split(",")).collect(Collectors.toList());
                Random rand = new Random();
                String mobile = phones.get(rand.nextInt(phones.size()));
                SysUser friend = sysUserMapper.findUserByPhone(mobile);
                if (friend != null) {
                    imUserFriendService.registerUserBindCustomerService(teacher.getUserId(),
                            Collections.singletonList(friend.getId()), ClientEnum.TEACHER);
                }
            }
        } else {
            // 如果机构解绑，更新机构ID为-1
            if (Boolean.TRUE.equals(teacherSubmitReq.getBindTenant())) {
                teacherSubmitReq.setTenantId(-1L);
            }
            if (!teacher.getTenantId().equals(teacherSubmitReq.getTenantId())) {
                if (teacherSubmitReq.getTenantId().equals(-1L)) {
                    // 平台老师处理流程
                    if (ESettlementFrom.TENANT.equals(teacherSubmitReq.getSettlementFrom())) {
                        // 解绑后，结算方式如果是机构，默认调整为老师
                        teacherSubmitReq.setSettlementFrom(ESettlementFrom.TEACHER);
                        teacherSubmitReq.setIsSettlement(true);
                    }
                }

                TeacherWrapper.UpdateTenant updateTenant = new TeacherWrapper.UpdateTenant();
                updateTenant.setTeacherId(teacher.getUserId());
                updateTenant.setTenantId(teacherSubmitReq.getTenantId());
                updateTenant(updateTenant, teacherSubmitReq.getUpdateBy());
            }

            teacher.setUpdateTime(new Date());
            teacher = getTeacherDetil(teacher, teacherSubmitReq);
            if (null == teacher.getEntryAuthDate() || null == teacher.getMusicianDate()) {
                baseMapper.update(teacher, Wrappers.<Teacher>lambdaUpdate()
                        .set(Teacher::getEntryAuthDate, teacher.getEntryAuthDate())
                        .set(Teacher::getMusicianDate, teacher.getMusicianDate())
                        .eq(Teacher::getUserId, teacher.getUserId())
                );
            }
            // 老师头像
            teacher.setAvatar(Optional.ofNullable(teacherSubmitReq.getAvatar()).orElse(teacher.getAvatar()));
            baseMapper.updateById(teacher);
        }

        return teacher;
    }

    /***
     * 封装用户信息
     * @author liweifan
     * @updateTime 2022/3/23 17:23
     */
    private SysUser getUserDetil(SysUser sysUser, TeacherSubmitReq teacherSubmitReq) throws BizException {
        if (!teacherSubmitReq.getIdCardNo().equals(sysUser.getIdCardNo())
                || !teacherSubmitReq.getRealName().equals(sysUser.getRealName())) {

            //实名信息
            RealnameAuthReq realNameAuthDto = new RealnameAuthReq();
            realNameAuthDto.setIdCardNo(teacherSubmitReq.getIdCardNo());
            realNameAuthDto.setRealName(teacherSubmitReq.getRealName());
            realNameAuthDto.setSave(false);

            if (!realnameAuthenticationPlugin.verify(realNameAuthDto.getRealName(),realNameAuthDto.getIdCardNo())) {
                throw new BizException("实名认证未通过");
            }

            //通过身份证号获取身份信息
            IdcardInfoExtractor idcardInfo = new IdcardInfoExtractor(realNameAuthDto.getIdCardNo(), false);
            //身份证解析信息
            sysUser.setGender(idcardInfo.getGender());
            sysUser.setBirthdate(idcardInfo.getBirthday());
            sysUser.setRealName(teacherSubmitReq.getRealName());
            sysUser.setIdCardNo(teacherSubmitReq.getIdCardNo());
        }
        if (StringUtil.isEmpty(sysUser.getUserType())) {
            sysUser.setUserType("TEACHER");
        } else if (!sysUser.getUserType().contains("TEACHER")) {
            sysUser.setUserType(sysUser.getUserType() + ",TEACHER");
        }
        sysUser.setAvatar(teacherSubmitReq.getAvatar());
        sysUser.setUsername(teacherSubmitReq.getUsername());
        sysUser.setPhone(teacherSubmitReq.getPhone());
        return sysUser;
    }

    /***
     * 封装老师信息
     * @author liweifan
     * @param: teacherSubmitReq
     * @updateTime 2022/3/23 17:27
     * @return: com.yonge.cooleshow.biz.dal.entity.Teacher
     */
    private Teacher getTeacherDetil(Teacher teacher, TeacherSubmitReq teacherSubmitReq) {
        teacher.setSubjectId(teacherSubmitReq.getSubjectId());
        teacher.setEntryFlag(YesOrNoEnum.NO);
        teacher.setEntryAuthDate(null);
        teacher.setMusicianFlag(YesOrNoEnum.NO);
        teacher.setMusicianDate(null);
        teacher.setIsSettlement(teacherSubmitReq.getIsSettlement());
        teacher.setIsTestUser(teacherSubmitReq.getIsTestUser());
        teacher.setSettlementFrom(teacherSubmitReq.getSettlementFrom());
        teacher.setTenantId(teacherSubmitReq.getTenantId() == null ? -1L : teacherSubmitReq.getTenantId());
        teacher.setAvatar(Optional.ofNullable(teacherSubmitReq.getAvatar()).orElse(teacher.getAvatar()));
        if (StringUtil.isEmpty(teacherSubmitReq.getTeacherType())) {
            return teacher;
        }
        String[] teacherTypes = teacherSubmitReq.getTeacherType().split(",");
        for (String teacherType : teacherTypes) {
            if (TeacherTypeEnum.ENTRY.getCode().equals(teacherType)) {
                teacher.setEntryFlag(YesOrNoEnum.YES);
                teacher.setEntryAuthDate(new Date());
            }
            if (TeacherTypeEnum.MUSICIAN.getCode().equals(teacherType)) {
                teacher.setMusicianFlag(YesOrNoEnum.YES);
                teacher.setMusicianDate(new Date());
            }
        }
        return teacher;
    }

    @Override
    public Integer setSubject(Long id, String subjectIds) {
        Integer integer = baseMapper.setSubject(id, subjectIds);
        //清除老师声部缓存
        redissonClient.getBucket(CacheNameEnum.TEACHER_SUBJECT_ITEM.getRedisKey(id)).delete();
        return integer;
    }

    @Override
    public HttpResponseResult<TeacherHomeVo> queryTeacherHome(Long studentId, Long teacherId) {
        TeacherHomeVo data = queryUserInfo(teacherId).getData();
        if (null == data) {
            return HttpResponseResult.failed("未查询到用户信息");
        }

        if (null != studentId) {
            StudentStar studentStar = studentStarService.getByStudentIdAndTeacherId(studentId, teacherId);
            if (null == studentStar) {
                data.setIsStar(YesOrNoEnum.NO);
            } else {
                data.setIsStar(YesOrNoEnum.YES);
            }
        }
        return HttpResponseResult.succeed(data);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public HttpResponseResult<TeacherVo> saveTeacherStyle(TeacherDto teacherDto) {
        //校验敏感词
        if (wordFilter.include(teacherDto.getIntroduction(), 3)) {
            throw new BizException("文本包含敏感信息");
        }
        //修改老师信息
        int i = baseMapper.updateById(teacherDto);
        List<TeacherStyleVideo> styleVideo = teacherDto.getStyleVideo();

        Map<Long, TeacherStyleVideo> oldMap = teacherStyleVideoService.list(Wrappers.<TeacherStyleVideo>lambdaQuery()
                        .eq(TeacherStyleVideo::getUserId, teacherDto.getUserId()))
                .stream().collect(Collectors.toMap(TeacherStyleVideo::getId, o -> o));

        List<TeacherStyleVideo> createList = styleVideo.stream().filter(o -> o.getId() == null)
                .collect(Collectors.toList());


        createList.forEach(o -> {
            o.setUserId(teacherDto.getUserId());
            o.setAuthStatus(AuthStatusEnum.DOING);
            o.setAuditVersion(YesOrNoEnum.NO);
        });

        List<Long> oldIds = styleVideo.stream().filter(o -> o.getId() != null)
                .map(TeacherStyleVideo::getId).collect(Collectors.toList());
        //删除旧视频
        teacherStyleVideoService.removeByUserIdAndOldIds(teacherDto.getUserId(), oldIds);
        //保存新视频
        teacherStyleVideoService.batchAddStyleVideo(createList);

        styleVideo.removeAll(createList);

        //修改视频封面
        styleVideo.forEach(o -> {
            TeacherStyleVideo old = oldMap.get(o.getId());
            if (old != null && !o.getCover().equals(old.getCover())) {
                teacherStyleVideoService.update(Wrappers.<TeacherStyleVideo>lambdaUpdate()
                        .set(TeacherStyleVideo::getCover, o.getCover())
                        .set(TeacherStyleVideo::getAuthStatus, AuthStatusEnum.DOING)
                        .set(TeacherStyleVideo::getEntryFlag, YesOrNoEnum.NO)
                        .eq(TeacherStyleVideo::getId, o.getId()));
            }
        });

        return HttpResponseResult.succeed(detail(teacherDto.getUserId()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStyleVideo(Long userId, List<TeacherStyleVideo> styleVideo, String message) {

        if (styleVideo == null) {
            styleVideo = new ArrayList<TeacherStyleVideo>();
        }
        //修改老师信息

        List<TeacherStyleVideo> teacherStyleVideoList =
                teacherStyleVideoService.list(Wrappers.<TeacherStyleVideo>lambdaQuery()
                        .eq(TeacherStyleVideo::getUserId, userId));

        Map<Long, TeacherStyleVideo> oldMap =
                teacherStyleVideoList.stream().collect(Collectors.toMap(TeacherStyleVideo::getId, o -> o));

        List<TeacherStyleVideo> createList = styleVideo.stream().filter(o -> o.getId() == null)
                .collect(Collectors.toList());


        createList.forEach(o -> {
            o.setUserId(userId);
            o.setAuthStatus(AuthStatusEnum.PASS);
        });

        List<Long> oldIds = styleVideo.stream().filter(o -> o.getId() != null)
                .map(TeacherStyleVideo::getId).collect(Collectors.toList());

        for (TeacherStyleVideo tv : teacherStyleVideoList) {
            if (tv.getAuthStatus() == AuthStatusEnum.DOING) {
                oldIds.add(tv.getId());
            }
        }
        //删除旧视频
        teacherStyleVideoService.removeByUserIdAndOldIds(userId, oldIds);
        //保存新视频
        teacherStyleVideoService.batchAddStyleVideo(createList);

        styleVideo.removeAll(createList);

        //修改视频封面
        styleVideo.forEach(o -> {
            TeacherStyleVideo old = oldMap.get(o.getId());
            if (!o.getCover().equals(old.getCover())) {
                teacherStyleVideoService.update(Wrappers.<TeacherStyleVideo>lambdaUpdate()
                        .set(TeacherStyleVideo::getCover, o.getCover())
                        .set(TeacherStyleVideo::getAuthStatus, AuthStatusEnum.PASS)
                        .eq(TeacherStyleVideo::getId, o.getId()));
            }
        });

        //发送推送
        try {
            //  发送消息
            SysUser user = userFeignService.queryUserById(userId);

            Map<Long, String> receivers = new HashMap<>();
            receivers.put(userId, user.getPhone());

            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG,
                    MessageTypeEnum.CUSTOME_MESSAGE_PUSH, receivers, null, 0,
                    null, ClientEnum.TEACHER.getCode(), message);

        } catch (Exception e) {
            log.error("[老师风采修改]发送消息失败--> {}", e.fillInStackTrace());
        }

        return true;
    }

    @Override
    public HttpResponseResult<Boolean> addHomeBrowse(Long userId) {
        Integer num = baseMapper.addHomeBrowse(userId);
        return HttpResponseResult.succeed(num > 0);
    }

    @Override
    public List<Subject> querySubjectItem(Long userId, String type) {
        //先查询自己的声部
        List<Subject> subjectList = querySubject(userId);

        List<Subject> cacheByType = getCacheByType(userId, type);
        if (CollectionUtils.isNotEmpty(cacheByType)) {
            subjectList.addAll(cacheByType);
        }
        return subjectList;
    }

    private List<Subject> getCacheByType(Long userId, String type) {
        RMap<String, List<Subject>> map = redissonClient.getMap(CacheNameEnum.TEACHER_SUBJECT_ITEM.getRedisKey(userId));
        //设置过期时间
        map.expire(CacheNameEnum.TEACHER_SUBJECT_ITEM.getDuration().toMinutes(),
                TimeUnit.MINUTES);

        if (StringUtil.isEmpty(type)) {
            List<Subject> subjectList = map.get("ALL");
            if (CollectionUtils.isEmpty(subjectList)) {
                subjectList = baseMapper.querySubjectItem(userId, null);
                map.put("ALL", subjectList);
            }
            return subjectList;
        } else {
            List<Subject> subjectList = map.get(type);
            if (CollectionUtils.isEmpty(subjectList)) {
                subjectList = baseMapper.querySubjectItem(userId, type);
                map.put(type, subjectList);
            }
            return subjectList;
        }
    }


    @Override
    public IPage<MyFens> queryMyFans(IPage<MyFens> page, Long teacherId) {
        List<MyFens> teacherVos = baseMapper.queryMyFans(page,
                TeacherQueryInfo.FansQuery.builder().teacherId(teacherId).build());
        return page.setRecords(teacherVos);
    }

    /**
     * 老师粉丝查询
     *
     * @param page  IPage<MyFens>
     * @param query TeacherQueryInfo.FansQuery
     * @return IPage<MyFens>
     */
    @Override
    public IPage<MyFens> queryMyFans(IPage<MyFens> page, TeacherQueryInfo.FansQuery query) {

        List<MyFens> teacherVos = baseMapper.queryMyFans(page, query);
        return page.setRecords(teacherVos);
    }

    @Override
    public void setTeacherTag(Long userId, TeacherTagEnum teacherTagEnum) {
        TeacherVo teacherVo = this.detail(userId);
        if (teacherVo == null) {
            return;
        }
        if (StringUtil.isEmpty(teacherVo.getTag())) {
            teacherVo.setTag(teacherTagEnum.getCode());
            setTagTime(teacherTagEnum, teacherVo);
        } else if (teacherVo.getTag().contains(teacherTagEnum.getCode())) {
            return;
        } else {
            teacherVo.setTag(teacherVo.getTag() + "," + teacherTagEnum.getCode());
            setTagTime(teacherTagEnum, teacherVo);
        }


        this.updateById(teacherVo);
    }

    @Override
    public List<HotTeacherVo> queryHotTeacherList(Long userId) {
        List<Long> watchTeacherIdList = new ArrayList<Long>();

        List<StudentStar> studentStarList = studentStarDao.queryByStudentId(userId);
        if (studentStarList != null && studentStarList.size() > 0) {
            watchTeacherIdList = studentStarList.stream().map(StudentStar::getTeacherId).collect(Collectors.toList());
        }

        Student student = studentService.getById(userId);
        Long subjectId = null;
        if (student.getSubjectId() != null) {
            subjectId = Long.parseLong(student.getSubjectId());
        }

        List<HotTeacherVo> hotTeacherList = baseMapper.queryHotTeacherList(subjectId);
        for (HotTeacherVo vo : hotTeacherList) {
            if (watchTeacherIdList.contains(vo.getUserId())) {
                vo.setWatch(true);
            }
        }

        return hotTeacherList;
    }

    private void setTagTime(TeacherTagEnum teacherTagEnum, TeacherVo teacherVo) {
        if (teacherTagEnum.equals(TeacherTagEnum.LIVE)) {
            teacherVo.setLiveDate(new Date());
        } else if (teacherTagEnum.equals(TeacherTagEnum.MUSIC)) {
            teacherVo.setLiveDate(new Date());
        } else if (teacherTagEnum.equals(TeacherTagEnum.STYLE)) {
            teacherVo.setLiveDate(new Date());
        } else if (teacherTagEnum.equals(TeacherTagEnum.VIDEO)) {
            teacherVo.setLiveDate(new Date());
        }
    }


    /**
     * 老师详情信息
     *
     * @param teacherId 用户ID
     * @return TeacherVo
     */
    @Override
    public TeacherVo findTeacherDetailInfo(Long teacherId) {

        // 用户详情基本信息
        TeacherVo teacherInfo = detail(teacherId);

        if (Objects.nonNull(teacherInfo)) {

            // 设置默认数据
            teacherInfo
                    .starGrade(0)
                    .fansNum(0)
                    .expTime(0)
                    .unExpTime(0)
                    .musicSheetNum(0)
                    .musicAlbumNum(0)
                    .studentNums(0);

            // 老师相关统计信息
            TeacherTotal total = totalService.getTotalById(teacherId);

            if (Objects.nonNull(total)) {

                teacherInfo
                        .starGrade(total.getStarGrade().intValue())
                        .fansNum(total.getFansNum())
                        .expTime(total.getExpTime())
                        .unExpTime(total.getUnExpTime())
                        .musicAlbumNum(total.getMusicAlbumNum())
                        .musicSheetNum(total.getMusicSheetNum());
            }

            // 老师学生人数统计
            Map<Long, Integer> studentNumsMap =
                    getBaseMapper().selectTeacherStudentNumberStatInfo(Lists.newArrayList(teacherId)).stream()
                            .collect(Collectors.toMap(StatGroupWrapper::getId, StatGroupWrapper::getTotal,
                                    (o, n) -> n));

            teacherInfo.setStudentNums(studentNumsMap.getOrDefault(teacherId, 0));
        }

        return teacherInfo;
    }

    /**
     * 老师统计指标信息
     *
     * @param userId 用户ID
     * @return TeacherWrapper.TeacherStatInfo
     */
    @Override
    public TeacherWrapper.TeacherStatInfo findTeacherStatInfoById(Long userId) {

        TeacherWrapper.TeacherStatInfo wrapper = TeacherWrapper.TeacherStatInfo.builder()
                .fansNum(0)
                .studentNums(0)
                .starGrade(0)
                .expTime(0)
                .unExpTime(0)
                .musicAlbumNum(0)
                .musicSheetNum(0)
                .build();

        // 查询老师统计指标
        TeacherTotal total = totalService.getTotalById(userId);
        if (Objects.nonNull(total)) {

            wrapper.starGrade(total.getStarGrade().intValue())
                    .fansNum(total.getFansNum())
                    .expTime(total.getExpTime())
                    .unExpTime(total.getUnExpTime())
                    .musicAlbumNum(total.getMusicAlbumNum())
                    .musicSheetNum(total.getMusicSheetNum());
        }

        // 老师学生端人数统计
        List<Long> teacherIds = Lists.newArrayList(userId);
        Map<Long, Integer> studentNumsMap = getBaseMapper().selectTeacherStudentNumberStatInfo(teacherIds).stream()
                .collect(Collectors.toMap(StatGroupWrapper::getId, StatGroupWrapper::getTotal, (o, n) -> n));

        wrapper.setStudentNums(studentNumsMap.getOrDefault(userId, 0));

        return wrapper;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateTenant(TeacherWrapper.UpdateTenant updateTenant,Long userId) {
        Teacher teacher = this.getById(updateTenant.getTeacherId());
        if (teacher.getTenantId().equals(updateTenant.getTenantId())) {
            return;
        }
        Long oldTenantId = teacher.getTenantId();
        if (oldTenantId != -1L) {
            // 判断是否存在机构小组群主身份
            QueryWrapper<TenantGroup> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(TenantGroup::getTenantId, oldTenantId)
                    .eq(TenantGroup::getAdminId, teacher.getUserId());
            Integer count = tenantGroupMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new BizException("该老师存在机构小组负责人身份，请先更换老师或者退出小组");
            }

            // 机构老师处理流程
            List<String> imGroupIds = imGroupMemberService.lambdaQuery()
                    .eq(ImGroupMember::getUserId, teacher.getUserId())
                    .eq(ImGroupMember::getIsAdmin, true)
                    .eq(ImGroupMember::getRoleType, ImGroupMemberRoleType.TEACHER)
                    .list().stream().map(ImGroupMember::getGroupId).distinct().collect(Collectors.toList());
            if (!imGroupIds.isEmpty()) {
                List<ImGroup> imGroups = imGroupService.lambdaQuery()
                        .in(ImGroup::getId, imGroupIds)
                        .eq(ImGroup::getType, ImGroupType.ORG)
                        .list();
                imGroups.forEach(next -> {
                    try {
                        imGroupService.dismiss(next.getId());
                    } catch (Exception e) {
                        log.error("老师修改机构，解散机构群失败：{}", e.getMessage());
                    }
                });
            }
            // 删除好友关系
            imUserFriendService.delStudentFriendByTenantId(teacher.getTenantId(), teacher.getUserId(), ClientEnum.TEACHER.getCode());
            addBindUnBindRecord(teacher.getUserId(), teacher.getTenantId(), false);
            SysUser sysUser = sysUserMapper.getByUserId(teacher.getUserId());
            sendBindUnBindSMS(teacher.getUserId(), sysUser.getPhone(), MessageTypeEnum.TEACHER_UNBIND_TENANT, teacher.getTenantId());

        }

        long tenantId = Optional.ofNullable(updateTenant.getTenantId()).orElse(-1L);
        if (tenantId == -1L) {
            // 平台老师处理流程
            if (ESettlementFrom.TENANT.equals(teacher.getSettlementFrom())) {
                // 解绑后，结算方式如果是机构，默认调整为老师
                teacher.setSettlementFrom(ESettlementFrom.TEACHER);
                teacher.setIsSettlement(true);
            }
        }else {
            // 机构老师与学生互加好友关系
            // 自动与机构学生成为好友
            Set<Long> collect = studentService.lambdaQuery()
                    .eq(Student::getTenantId, updateTenant.getTenantId()).list().stream()
                    .map(Student::getUserId)
                    .collect(Collectors.toSet());

            if (!collect.isEmpty()) {
                imUserFriendService.saveUserFriend(teacher.getUserId(), collect);
            }
            addBindUnBindRecord(teacher.getUserId(),updateTenant.getTenantId(),true);
            SysUser sysUser = sysUserMapper.getByUserId(teacher.getUserId());
            sendBindUnBindSMS(teacher.getUserId(), sysUser.getPhone(), MessageTypeEnum.TEACHER_BIND_TENANT, updateTenant.getTenantId());
        }

        teacher.setTenantId(updateTenant.getTenantId());
        this.updateById(teacher);

        Optional<TenantUnbindRecord> first = tenantUnbindRecordMapper.getRecord(oldTenantId,
                        updateTenant.getTeacherId(), "TEACHER").stream()
                .filter(next -> next.getStatus().equals(ETenantUnBindAuditStatus.DOING)).findFirst();
        if (first.isPresent()) {
            TenantUnbindRecord tenantUnbindRecord = first.get();
            tenantUnbindRecord.setStatus(ETenantUnBindAuditStatus.CLOSE);
            tenantUnbindRecord.setReason("机构发生变更，关闭申请");
            tenantUnbindRecord.setVerifyUserId(userId);
            tenantUnbindRecord.setInterveneTime(new Date());
            tenantUnbindRecordMapper.updateById(tenantUnbindRecord);

            TenantUnbindHistory history = JSON.parseObject(JSON.toJSONString(tenantUnbindRecord),
                    TenantUnbindHistory.class);
            tenantUnbindHistoryMapper.insert(history);
        }

    }

    @Override
    public UserPaymentOrderWrapper.AccountTenantTo teacherSettlementFrom(Long teacherId, Long recomUserId) {
        // 判断分润给机构 还是给老师


        UserPaymentOrderWrapper.AccountTenantTo accountTenantTo = new UserPaymentOrderWrapper.AccountTenantTo();

        if (teacherId != null) {
            Teacher teacher = getById(teacherId);
            if (teacher.getIsSettlement() !=null && !teacher.getIsSettlement()) {
                accountTenantTo.setIncomeTenant(0L);
            } else if (teacher.getTenantId() != null && teacher.getTenantId() > 0) {
                accountTenantTo.setIncomeTenant(teacher.getTenantId());
                if (ESettlementFrom.TEACHER.equals(teacher.getSettlementFrom())) {
                    accountTenantTo.setIncomeTeacher(true);
                }
            } else {
                // 分润给老师
                accountTenantTo.setIncomeTenant(-1L);
                accountTenantTo.setIncomeTeacher(true);
            }
        }


        if (recomUserId != null) {
            Teacher teacher = getById(recomUserId);
            if (teacher.getIsSettlement() !=null && !teacher.getIsSettlement()) {
                accountTenantTo.setShareTenant(0L);
            } else if (teacher.getTenantId() != null && teacher.getTenantId() > 0) {
                accountTenantTo.setShareTenant(teacher.getTenantId());
                if (ESettlementFrom.TEACHER.equals(teacher.getSettlementFrom())) {
                    accountTenantTo.setShareTeacher(true);
                }
            } else {
                // 分润给老师
                accountTenantTo.setShareTenant(-1L);
                accountTenantTo.setShareTeacher(true);
            }
        }

        return accountTenantTo;
    }

    @Override
    public Map<Long, Teacher> getMapByIds(List<Long> teacherIds) {

        if (CollectionUtils.isEmpty(teacherIds)) {
            return Collections.emptyMap();
        }

        List<Teacher> teachers = getBaseMapper().selectBatchIds(teacherIds);
        if (CollectionUtils.isEmpty(teachers)) {
            return Collections.emptyMap();
        }

        return teachers.stream().collect(Collectors.toMap(Teacher::getUserId, o -> o, (o, n) -> n));
    }

    private void addBindUnBindRecord(Long teacherId, Long tenantId, Boolean bind) {
        UserTenantBindRecord bindRecord = new UserTenantBindRecord();
        bindRecord.setUserId(teacherId);
        bindRecord.setUserType("TEACHER");
        bindRecord.setTenantId(tenantId);
        bindRecord.setBindStatus(bind);
        bindRecord.setBindTime(new Date());
        userTenantBindRecordMapper.add(bindRecord);
    }

    private void sendBindUnBindSMS(Long userId, String phone, MessageTypeEnum messageType, Long tenantId) {
        TenantInfo tenantInfo = tenantInfoService.getById(tenantId);
        Map<Long, String> receivers = new HashMap<>();
        receivers.put(userId, phone);
        sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, messageType,
                receivers, null, 0, null, ClientEnum.SYSTEM.getCode(), tenantInfo.getName());
    }
}