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

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
import com.yonge.cooleshow.auth.api.entity.SysUser;
import com.yonge.cooleshow.biz.dal.dao.CourseScheduleDao;
import com.yonge.cooleshow.biz.dal.dao.CourseScheduleRepliedDao;
import com.yonge.cooleshow.biz.dal.dao.CourseScheduleStudentPaymentDao;
import com.yonge.cooleshow.biz.dal.dto.search.MyCourseSearch;
import com.yonge.cooleshow.biz.dal.entity.CourseSchedule;
import com.yonge.cooleshow.biz.dal.entity.CourseScheduleReplied;
import com.yonge.cooleshow.biz.dal.entity.CourseScheduleStudentPayment;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
import com.yonge.cooleshow.biz.dal.service.CourseRepliedService;
import com.yonge.cooleshow.biz.dal.service.SysMessageService;
import com.yonge.cooleshow.biz.dal.vo.CourseRepliedVo;
import com.yonge.cooleshow.biz.dal.vo.MyRepliedVo;
import com.yonge.cooleshow.biz.dal.vo.RepliedCountVo;
import com.yonge.cooleshow.biz.dal.wordfilter.WordFilter;
import com.yonge.toolset.base.exception.BizException;
import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: cy
 * @Date: 2022/4/12
 */
@Service
public class CourseRepliedServiceImpl extends ServiceImpl<CourseScheduleRepliedDao, CourseScheduleReplied> implements CourseRepliedService {
    private final static Logger log = LoggerFactory.getLogger(CourseRepliedServiceImpl.class);

    @Autowired
    private SysUserFeignService sysUserFeignService;
    @Autowired
    private SysMessageService sysMessageService;
    @Autowired
    private CourseScheduleRepliedDao repliedDao;
    @Autowired
    private CourseScheduleDao scheduleDao;
    @Autowired
    private CourseScheduleStudentPaymentDao paymentDao;
    @Autowired
    private WordFilter wordFilter;

    public CourseScheduleRepliedDao getDao() {
        return repliedDao;
    }

    /**
     * @Description: 首页-我的课程-课程详情-评价陪练课
     * @Author: cy
     * @Date: 2022/4/12
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void replied(CourseScheduleReplied replied, SysUser sysUser) {
        if (wordFilter.include(replied.getStudentReplied(), 3)) {
            throw new BizException("文本包含敏感信息");
        }
        if (wordFilter.include(replied.getTeacherReplied(), 3)) {
            throw new BizException("文本包含敏感信息");
        }
        Long userId = sysUser.getId();
        Long scheduleId = replied.getCourseScheduleId();
        Long studentId = replied.getStudentId();

        CourseSchedule courseSchedule = scheduleDao.selectById(scheduleId);
        if (courseSchedule == null) {
            throw new RuntimeException("课程不存在");
        }
        if (courseSchedule.getStatus().equals(CourseScheduleEnum.NOT_START.getCode())) {
            throw new RuntimeException("课程未开始无法评论");
        }

        //当前用户为老师
        if (userId.equals(courseSchedule.getTeacherId())) {
            if (studentId == null) {
                throw new RuntimeException("评价的学生id不能为空");
            }
            isPayment(studentId, scheduleId);
            replied.setScore(null);
            replied.setStudentReplied(null);
            replied.setTeacherRepliedTime(new Date());
            if (!repliedIsNull(replied)) {
                repliedDao.updateReplied(replied);
            }else {
                repliedDao.insert(replied);
            }
        }else {
            //当前用户为学员
            isPayment(userId, scheduleId);
            replied.setStudentId(userId);
            replied.setTeacherReplied(null);
            replied.setStudentRepliedTime(new Date());
            if (!repliedIsNull(replied)) {
                repliedDao.updateReplied(replied);
            }else {
                repliedDao.insert(replied);
            }
            repliedSend(courseSchedule.getTeacherId(), userId);
        }
    }

    /**
     * @Description: 陪练课评价消息推送
     * @Author: cy
     * @Date: 2022/5/6
     */
    public void repliedSend(Long teacherId, Long studentId) {
        try {
            SysUser student = sysUserFeignService.queryUserById(studentId);
            SysUser teacher = sysUserFeignService.queryUserById(teacherId);

            Map<Long, String> teacherReceivers = new HashMap<>();
            teacherReceivers.put(teacherId, teacher.getPhone());

            String url = sysMessageService.selectConfigUrl(MessageTypeEnum.STUDENT_EVALUATE_TEACHER_PRACTICE.getCode());
            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_EVALUATE_TEACHER_PRACTICE,
                    teacherReceivers, null, 0, url, ClientEnum.TEACHER.getCode(),
                    student.getUsername());
            log.info("send success {}", MessageTypeEnum.STUDENT_EVALUATE_TEACHER_PRACTICE);
        } catch (Exception e) {
            log.error("send fail {}", MessageTypeEnum.STUDENT_EVALUATE_TEACHER_PRACTICE);
            e.printStackTrace();
        }
    }

    /**
     * @Description: 判断评论是否存在
     * @Author: cy
     * @Date: 2022/5/6
     */
    public boolean repliedIsNull(CourseScheduleReplied replied) {
        QueryWrapper<CourseScheduleReplied> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("student_id_", replied.getStudentId());
        queryWrapper.eq("course_schedule_id_", replied.getCourseScheduleId());
        queryWrapper.eq("course_group_id_", replied.getCourseGroupId());
        queryWrapper.eq("course_group_type_", CourseScheduleEnum.PRACTICE.getCode());
        CourseScheduleReplied scheduleReplied = repliedDao.selectOne(queryWrapper);
        return scheduleReplied == null ? true : false;
    }

    /**
     * @Description: 校验当前用户是否购买课程
     * @Author: cy
     * @Date: 2022/5/6
     */
    public void isPayment(Long userId, Long scheduleId) {
        QueryWrapper<CourseScheduleStudentPayment> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id_", userId);
        wrapper.eq("course_id_", scheduleId);
        wrapper.eq("course_type_", CourseScheduleEnum.PRACTICE.getCode());
        CourseScheduleStudentPayment payment = paymentDao.selectOne(wrapper);
        if (payment == null) {
            throw new RuntimeException("学生未购买该课无法评论");
        }
    }

    /**
     * @Description: 首页-我的课程-课程详情-查询评价
     * @Author: cy
     * @Date: 2022/4/12
     */
    @Override
    public CourseRepliedVo selectReplied(CourseScheduleReplied replied) {
        CourseRepliedVo repliedVo = repliedDao.selectReplied(replied);
        return repliedVo;
    }

    /**
     * @Description: 首页-我收到的评价
     * @Author: cy
     * @Date: 2022/4/13
     */
    @Override
    public IPage<MyRepliedVo> myReplied(IPage<MyRepliedVo> page, MyCourseSearch search) {
        return page.setRecords(repliedDao.myReplied(page, search));
    }

    /**
     * @Description: 当日陪练课未对老师评价（每晚9点，已评价不发）
     * @Author: cy
     * @Date: 2022/5/6
     */
    public void noRepliedTeacher(){
        String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        //统计当日所有购课学员
        List<RepliedCountVo> repliedCounts=scheduleDao.countAllReplie(today);
        for (RepliedCountVo repliedCount : repliedCounts) {
            Long userId = repliedCount.getUserId();

            Integer expCount = repliedCount.getCount();//应该评论课程数
            Integer actCount=scheduleDao.countReplies(userId);//已评论课程数
            int count = expCount - actCount;
            if (count>0){//有课程未评价
                Map<Long, String> studentReceivers = new HashMap<>();
                studentReceivers.put(userId, repliedCount.getPhone());
                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.NOT_EVALUATE_TEACHER_PRACTICE,
                        studentReceivers, null, 0, null, ClientEnum.STUDENT.getCode(),
                        count);
                log.info("send success {}",MessageTypeEnum.NOT_EVALUATE_TEACHER_PRACTICE);
            }
        }
    }
}