package com.hc.business.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hc.business.dto.CourseVideoDto;
import com.hc.business.dto.TypeCourseDto;
import com.hc.business.dto.UserCourseDto;
import com.hc.business.model.Course;
import com.hc.business.model.CourseChapterVideo;
import com.hc.business.model.UserCourse;
import com.hc.business.model.UserVideoPosition;
import com.hc.business.mapper.CourseChapterVideoMapper;
import com.hc.business.mapper.CourseMapper;
import com.hc.business.mapper.UserCourseMapper;
import com.hc.business.service.CourseChapterService;
import com.hc.business.service.CourseService;
import com.hc.business.service.UserVideoPositionService;
import com.hc.core.utils.tool.status.CodeFlagEnum;
import com.hc.core.utils.tool.Compute;
import org.springframework.stereotype.Service;
import org.springframework.beans.BeanUtils;

import java.util.*;

/**
 * 课程表(Course)表服务实现类
 *
 * @author java
 * @since 2020-11-09 10:04:46
 */

@Service("courseService")
public class CourseServiceImpl implements CourseService {

    private final CourseChapterService courseChapterService;

    private final CourseChapterVideoMapper courseChapterVideoMapper;

    private final UserVideoPositionService userVideoPositionService;

    private final CourseMapper courseMapper;

    private final UserCourseMapper userCourseMapper;

    public CourseServiceImpl(CourseMapper courseMapper,
                             UserCourseMapper userCourseMapper,
                             CourseChapterVideoMapper courseChapterVideoMapper,
                             UserVideoPositionService userVideoPositionService,
                             CourseChapterService courseChapterService) {
        this.courseMapper = courseMapper;
        this.userCourseMapper = userCourseMapper;
        this.courseChapterVideoMapper = courseChapterVideoMapper;
        this.userVideoPositionService = userVideoPositionService;
        this.courseChapterService = courseChapterService;
    }

    /**
     * 通过ID查询单条数据
     *
     * @param courseId 主键
     * @return 实例对象
     */
    @Override
    public Course queryById(Integer courseId) {
        return this.courseMapper.selectByPrimaryKey(courseId);
    }

    /**
     * 新增数据
     *
     * @param course 实例对象
     * @return 实例对象
     */
    @Override
    public Course insert(Course course) {
        course.setIsValid(CodeFlagEnum.OBJECT_ENABLE_CODE.getCode());
        this.courseMapper.insert(course);
        return course;
    }

    /**
     * 修改数据
     *
     * @param course 实例对象
     * @return 实例对象
     */
    @Override
    public Course update(Course course) {
        this.courseMapper.updateByPrimaryKeySelective(course);
        return this.queryById(course.getCourseId());
    }

    /**
     * 通过主键删除数据
     *
     * @param courseId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer courseId) {
//        return this.courseMapper.deleteByPrimaryKey(courseId) > 0;
        Course course = queryById(courseId);
        if (!Objects.isNull(course)) {
            course.setIsValid(CodeFlagEnum.OBJECT_DISABLED_CODE.getCode());
            this.courseMapper.updateByPrimaryKeySelective(course);
            return true;
        }
        return false;
    }

    @Override
    public List<Course> queryTeacherName(String name) {
        return this.courseMapper.queryTeacherName(name);
    }

    @Override
    public List<Course> queryCourseName(String name) {
        return this.courseMapper.queryCourseName(name);
    }

    /**
     * 分页查询多条数据
     *
     * @param page 页码
     * @param size 查询条数
     * @return 对象列表
     */
    @Override
    public PageInfo queryAllByLimit(int page, int size, Integer valid) {
        PageHelper.startPage(page, size);
        List<Course> courses = this.courseMapper.queryAll(valid);
        return new PageInfo(courses);
    }

    @Override
    public PageInfo queryAllByLimitAndTypeId(int page, int size, Integer typeId) {
        PageHelper.startPage(page, size);
        List<TypeCourseDto> courses = this.courseMapper.queryByTypeId(typeId);
        for (TypeCourseDto course : courses) {
            List<CourseChapterVideo> videoList = courseChapterVideoMapper.selectVideoByCourseId(course.getCourseId());
            course.setVideoList(videoList);
        }
        return new PageInfo(courses);
    }


    @Override
    public List<CourseChapterVideo> getAllVideos(Integer courseId){
        return courseChapterVideoMapper.selectVideoByCourseId(courseId);
    }

    //重写课程，缓存以及计算用户总体进度的方法和结构,
    //继续教育不区分章节，但是支持多个视频
    @Override
    public List<CourseVideoDto> getCourseChapterAndVideoPosition(Integer courseId, Integer userId, Integer classId) {

        boolean update = false;
        List<CourseVideoDto> videoListDto = new ArrayList<CourseVideoDto>();

        List<CourseChapterVideo> videoList = courseChapterVideoMapper.selectVideoByCourseId(courseId);

        Double totalPercent = Double.valueOf("0");
        if (videoList.size() > 0) {

            for (int vindex = 0; vindex < videoList.size(); vindex++) {

                CourseVideoDto dto = new CourseVideoDto();
                dto.setVideo(videoList.get(vindex));

                Map<String, String> map = userVideoPositionService.findVideoPosition(userId, videoList.get(vindex).getVideoId(), courseId, classId);
                // 填入播放记录
                if ((null != map) && (map.size() > 0)) {
                    UserVideoPosition userVideoPosition = new UserVideoPosition();
                    Double videotime = null;
                    Double position = null;
                    if (map.containsKey("update")) {
                        update = true;
                    }
                    try {
                        videotime = Double.valueOf(map.get("videotime"));
                        position = Double.valueOf(map.get("position"));

                    } catch (Exception e) {
                        //视频位置，长度有问题，处理吓一条
                        //视频进度有问题，不能直接跳过。否则对于 已经缓存了但是没有正确位置信息的视频就会漏掉
                        //这类数据按照位置0处理
                        userVideoPosition.setVideoTime("0");
                        userVideoPosition.setVideoPosition("0");
                        userVideoPosition.setVideoId(videoList.get(0).getVideoId());
                        userVideoPosition.setUserId(userId);
                        //没有正确数据的视频，进度按照0计算，返回结构体
                        //totalPercent = Compute.add(totalPercent, Compute.div(position, videotime, 2));
                        dto.setPosition(userVideoPosition);

                        //解析得视频进度数据不正确，但是依然要返回一个空得结构体。否则会造成丢掉数据有问题得视频
                        videoListDto.add(dto);
                        continue;
                    }

                    userVideoPosition.setVideoTime(map.get("videotime"));
                    userVideoPosition.setVideoPosition(map.get("position"));
                    userVideoPosition.setVideoId(videoList.get(0).getVideoId());
                    userVideoPosition.setUserId(userId);
                    totalPercent = Compute.add(totalPercent, Compute.div(position, videotime, 2));
                    dto.setPosition(userVideoPosition);
                }

                videoListDto.add(dto);
            }


            //计算平均进度
            //计算平均进度
            totalPercent = Compute.div(totalPercent, videoList.size(), 2);
            if (true == update) {
                //如果章节进度有更新，需要从新计算课程总体进度，并更新到数据库
                //TODO 查询课程进度
                List<UserCourseDto> cardCourseList = userCourseMapper.selectUserCourseProgress(userId, classId, courseId);
                if (cardCourseList.size() > 0) {
                    //课程进度有变化时 将查询的课程进度写入数据库
                    if (!totalPercent.equals(cardCourseList.get(0).getCoursePercent())) {
                        UserCourse userCourse = new UserCourse();
                        BeanUtils.copyProperties(cardCourseList.get(0), userCourse);
                        userCourse.setCoursePercent(totalPercent);
                        userCourseMapper.updateByPrimaryKeySelective(userCourse);
                    }
                } else {
                    //如果没有课程得记录，则增加记录
                    UserCourse userCourse = new UserCourse();
                    userCourse.setCoursePercent(totalPercent);
                    userCourse.setCourseId(courseId);
                    userCourse.setUserId(userId);
                    userCourse.setClassId(classId);
                    userCourseMapper.insert(userCourse);
                }

            }
        }
        return videoListDto;
    }
}
