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

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

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.google.common.collect.Lists;
import com.yonge.cooleshow.biz.dal.queryInfo.TeacherQueryInfo;
import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
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 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.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.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.Student;
import com.yonge.cooleshow.biz.dal.entity.StudentStar;
import com.yonge.cooleshow.biz.dal.entity.Subject;
import com.yonge.cooleshow.biz.dal.entity.Teacher;
import com.yonge.cooleshow.biz.dal.entity.TeacherAuthMusicianRecord;
import com.yonge.cooleshow.biz.dal.entity.TeacherStyleVideo;
import com.yonge.cooleshow.biz.dal.entity.TeacherTotal;
import com.yonge.cooleshow.biz.dal.entity.UserAccount;
import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
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.service.StudentService;
import com.yonge.cooleshow.biz.dal.service.StudentStarService;
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.vo.HotTeacherVo;
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.common.constant.SysConfigConstant;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.cooleshow.common.enums.CacheNameEnum;
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.utils.date.DateUtil;
import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
import com.yonge.toolset.utils.string.ValueUtil;

@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 StudentStarDao studentStarDao;
    
    @Autowired
    private StudentService studentService;
    
    @Autowired
    private SysMessageService sysMessageService;

    @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(num < 0 ? 0 : num);
        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);
        return detail;
    }

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

    @Override
    @Transactional(rollbackFor = BizException.class)
    public HttpResponseResult<Boolean> submit(TeacherSubmitReq teacherSubmitReq) throws BizException {
        if (null == teacherSubmitReq.getUserId()) {
            //创建
            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);

        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(num < 0 ? 0 : num);
        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 (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());

        // 老师学生人数统计
        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) {
            sysUser = insertSysUser(teacherSubmitReq);
            teacherSubmitReq.setUserId(sysUser.getId());
        } else {
            teacherSubmitReq.setUserId(sysUser.getId());
            updateSysUser(teacherSubmitReq);
        }
        //新增修改老师表
        insertOrUpdateTeacher(teacherSubmitReq);
        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);
        //初始密码，手机号后6位
        String password = sysUser.getPhone().substring(sysUser.getPhone().length() - 6);
        sysUser.setPassword(new BCryptPasswordEncoder().encode(password));
        //插入
        int num = employeeDao.insertSysUser(sysUser);
        if (num <= 0) {
            throw new BizException("插入用户信息失败");
        }
        //设置昵称
        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) {
        Teacher teacher = baseMapper.selectById(teacherSubmitReq.getUserId());
        if (null == teacher) {
            teacher = new Teacher();
            teacher.setUserId(teacherSubmitReq.getUserId());
            teacher = getTeacherDetil(teacher, teacherSubmitReq);
            baseMapper.insert(teacher);

            //插入老师账户表
            UserAccount oldAcc = userAccountService.getById(teacherSubmitReq.getUserId());
            if (null == oldAcc) {
                UserAccount userAccount = new UserAccount();
                userAccount.setUserId(teacherSubmitReq.getUserId());
                userAccountService.save(userAccount);
            }
        } else {
            teacher.setUpdateTime(new Date());
            teacher = getTeacherDetil(teacher, teacherSubmitReq);
            baseMapper.updateById(teacher);

            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())
                );
            }
        }

        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);

            HttpResponseResult<IdcardInfoExtractor> idcardInfoExtractorResult = userFeignService.realNameAuth(realNameAuthDto);
            if (!idcardInfoExtractorResult.getStatus() || null == idcardInfoExtractorResult.getData()) {
                throw new BizException("实名认证未通过");
            }
            //身份证解析信息
            IdcardInfoExtractor idcardInfo = idcardInfoExtractorResult.getData();
            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");
        }
        //设置默认头像
        if (StringUtil.isEmpty(sysUser.getAvatar())) {
            String defaultHeard = sysConfigService.findConfigValue(SysConfigConstant.DEFAULT_HEARD);
            sysUser.setAvatar(defaultHeard);
        }

        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());
        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;
        }
    }


    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;
    }

}