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

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.entity.SysUser;
import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
import com.yonge.cooleshow.biz.dal.dao.UserBindingTeacherDao;
import com.yonge.cooleshow.biz.dal.dto.search.QueryMyFollowSearch;
import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
import com.yonge.cooleshow.biz.dal.entity.StudentTotal;
import com.yonge.cooleshow.biz.dal.entity.Subject;
import com.yonge.cooleshow.biz.dal.entity.UserBindingTeacher;
import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
import com.yonge.cooleshow.biz.dal.service.TeacherService;
import com.yonge.cooleshow.common.enums.CacheNameEnum;
import com.yonge.cooleshow.biz.dal.service.StudentTotalService;
import com.yonge.cooleshow.biz.dal.vo.*;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.cooleshow.common.enums.UserLockFlag;
import com.yonge.toolset.base.util.StringUtil;
import com.yonge.toolset.utils.date.DateUtil;
import com.yonge.toolset.utils.string.ValueUtil;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yonge.cooleshow.biz.dal.entity.Student;
import com.yonge.cooleshow.biz.dal.dao.StudentDao;
import com.yonge.cooleshow.biz.dal.service.StudentService;

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


@Service
public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> implements StudentService {
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private StudentTotalService totalService;
    @Autowired
    private ImUserFriendService imUserFriendService;
    @Resource
    private UserBindingTeacherDao userBindingTeacherDao;
    @Autowired
    private StudentService studentService;
    @Resource
    private TeacherDao teacherDao;

    @Override
    public StudentVo detail(Long userId) {
        return baseMapper.detail(userId);
    }

    @Override
    public StudentVo detailByPhone(String phone) {
        return baseMapper.detailByPhone(phone);
    }

    @Override
    public IPage<StudentVo> selectPage(IPage<StudentVo> page, StudentSearch studentSearch) {
        return page.setRecords(baseMapper.selectPage(page, studentSearch));
    }

    @Override
    public StudentHomeVo queryUserInfo(SysUser user) {
        StudentVo detail = detail(user.getId());
        StudentHomeVo studentHomeVo = new StudentHomeVo();
        BeanUtils.copyProperties(detail, studentHomeVo);

        //身份证号、手机号脱敏
        studentHomeVo.setIdCardNo(ValueUtil.fuzzyIdCard(studentHomeVo.getIdCardNo()));
        studentHomeVo.setPhone(ValueUtil.fuzzyMobile(studentHomeVo.getPhone()));
        studentHomeVo.setHeardUrl(user.getAvatar());

        int num = DateUtil.daysBetween(new Date(), detail.getMembershipEndTime());
        studentHomeVo.setMembershipDays(num < 0 ? 0 : num);

        StudentTotal total = totalService.getTotalById(user.getId());
        if (null == total) {
            total = new StudentTotal();
        }

        studentHomeVo.setExerciseDays(null == total.getExerciseDays() ? 0 : total.getExerciseDays());
        studentHomeVo.setExerciseHours(null == total.getExerciseHours() ? 0 : total.getExerciseHours());
        studentHomeVo.setTestingNum(null == total.getTestingNum() ? 0 : total.getTestingNum());
        studentHomeVo.setFinshClassHours(null == total.getFinshHours() ? 0 : total.getFinshHours());
        studentHomeVo.setUnfinshClassHours(null == total.getUnfinshHours() ? 0 : total.getUnfinshHours());
        studentHomeVo.setStarTeacherNum(null == total.getStarTeacherNum() ? 0 : total.getStarTeacherNum());
        studentHomeVo.setMusicAlbumNum(null == total.getMusicAlbumNum() ? 0 : total.getMusicAlbumNum());
        studentHomeVo.setMusicSheetNum(null == total.getMusicSheetNum() ? 0 : total.getMusicSheetNum());
        return studentHomeVo;
    }

    @Override
    public Integer setSubject(Long id, String subjectIds) {
        return baseMapper.setSubject(id, subjectIds);
    }

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

    @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.STUDENT_SUBJECT_ITEM.getRedisKey(userId));
        //设置过期时间
        map.expire(CacheNameEnum.STUDENT_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<MyFollow> queryMyFollow(IPage<MyFollow> page, QueryMyFollowSearch query) {
        List<MyFollow> teacherVos = baseMapper.queryMyFollow(page, query);
        return page.setRecords(teacherVos);
    }

    @Override
    public HttpResponseResult<Map<String, TeacherVo>> bindTeacher(String phone, Long userId, Boolean isUpdate) {
        Map<String, TeacherVo> resMap = new HashMap<>();
        TeacherVo old = userBindingTeacherDao.getBindTeacherByPhone(phone);
        if (null != old) {
            //身份证号、手机号脱敏
            old.setIdCardNo(ValueUtil.fuzzyIdCard(old.getIdCardNo()));
            old.setPhone(ValueUtil.fuzzyMobile(old.getPhone()));
        }
        resMap.put("old", old);

        StudentVo studentVo = studentService.detailByPhone(phone);

        if (null == studentVo) {
            return HttpResponseResult.failed("未找到用户信息");
        }
        TeacherVo detail = teacherDao.detail(userId);
        if (null != detail) {
            //身份证号、手机号脱敏
            detail.setIdCardNo(ValueUtil.fuzzyIdCard(detail.getIdCardNo()));
            detail.setPhone(ValueUtil.fuzzyMobile(detail.getPhone()));
        }
        if (null == detail) {
            return HttpResponseResult.failed("未找老师信息");
        }
        if (UserLockFlag.LOCKED.equals(detail.getLockFlag())) {
            return HttpResponseResult.failed("老师被锁定");
        }
        if (null == old || (null != isUpdate && isUpdate)) {
            //更新
            //删除用户绑定
            userBindingTeacherDao.delete(Wrappers.<UserBindingTeacher>lambdaQuery()
                    .eq(UserBindingTeacher::getStudentId, studentVo.getUserId()));

            UserBindingTeacher userBindingTeacher = new UserBindingTeacher();
            userBindingTeacher.setTeacherId(userId);
            userBindingTeacher.setStudentId(studentVo.getUserId());
            userBindingTeacherDao.insert(userBindingTeacher);

            //学生老师增加好友关系
            Set<Long> studentIds = new HashSet<>();
            studentIds.add(studentVo.getUserId());
            imUserFriendService.saveUserFriend(userId, studentIds);
        }
        resMap.put("now", detail);
        return HttpResponseResult.succeed(resMap);
    }

}