package com.fs.course.service.impl;

import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import cn.hutool.json.JSONUtil;
import com.fs.common.core.domain.R;
import com.fs.common.utils.DateUtils;
import com.fs.course.domain.FsUserCourseStudy;
import com.fs.course.domain.FsUserCourseStudyLog;
import com.fs.course.domain.FsUserCourseVideo;
import com.fs.course.mapper.*;
import com.fs.course.param.FsUserCourseAddStudyCourseParam;
import com.fs.course.param.FsUserCourseGetIntegralParam;
import com.fs.course.param.FsUserCourseListUParam;
import com.fs.course.param.FsUserCourseParam;
import com.fs.course.param.newfs.FsUserCourseListParam;
import com.fs.course.vo.*;
import com.fs.course.vo.newfs.FsUserCourseListVO;
import com.fs.his.config.IntegralConfig;
import com.fs.his.domain.FsUser;
import com.fs.his.domain.FsUserIntegralLogs;
import com.fs.his.mapper.FsUserIntegralLogsMapper;
import com.fs.his.mapper.FsUserMapper;
import com.fs.his.service.IFsUserNewTaskService;
import com.fs.his.vo.OptionsVO;
import com.fs.system.service.ISysConfigService;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fs.course.domain.FsUserCourse;
import com.fs.course.service.IFsUserCourseService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 课程Service业务层处理
 *
 * @author fs
 * @date 2024-05-15
 */
@Service
public class FsUserCourseServiceImpl implements IFsUserCourseService
{
    @Autowired
    private FsUserCourseMapper fsUserCourseMapper;
    @Autowired
    private FsUserCourseCommentMapper fsUserCourseCommentMapper;
    @Autowired
    private FsUserCourseNoteMapper fsUserCourseNoteMapper;
    @Autowired
    private FsUserCourseVideoMapper fsUserCourseVideoMapper;
    @Autowired
    private FsUserCourseStudyMapper fsUserCourseStudyMapper;
    @Autowired
    private FsUserCourseStudyLogMapper fsUserCourseStudyLogMapper;
    @Autowired
    private FsUserIntegralLogsMapper fsUserIntegralLogsMapper;
    @Autowired
    private FsUserMapper fsUserMapper;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private IFsUserNewTaskService fsUserNewTaskService;
    /**
     * 查询课程
     *
     * @param courseId 课程主键
     * @return 课程
     */
    @Override
    public FsUserCourse selectFsUserCourseByCourseId(Long courseId)
    {
        return fsUserCourseMapper.selectFsUserCourseByCourseId(courseId);
    }

    /**
     * 查询课程列表
     *
     * @param fsUserCourse 课程
     * @return 课程
     */
    @Override
    public List<FsUserCourse> selectFsUserCourseList(FsUserCourse fsUserCourse)
    {
        return fsUserCourseMapper.selectFsUserCourseList(fsUserCourse);
    }

    /**
     * 新增课程
     *
     * @param fsUserCourse 课程
     * @return 结果
     */
    @Override
    public int insertFsUserCourse(FsUserCourse fsUserCourse)
    {
        fsUserCourse.setCreateTime(DateUtils.getNowDate());
        return fsUserCourseMapper.insertFsUserCourse(fsUserCourse);
    }

    /**
     * 修改课程
     *
     * @param fsUserCourse 课程
     * @return 结果
     */
    @Override
    public int updateFsUserCourse(FsUserCourse fsUserCourse)
    {
        fsUserCourse.setUpdateTime(DateUtils.getNowDate());
        return fsUserCourseMapper.updateFsUserCourse(fsUserCourse);
    }

    /**
     * 批量删除课程
     *
     * @param courseIds 需要删除的课程主键
     * @return 结果
     */
    @Override
    public int deleteFsUserCourseByCourseIds(Long[] courseIds)
    {
        return fsUserCourseMapper.deleteFsUserCourseByCourseIds(courseIds);
    }

    /**
     * 删除课程信息
     *
     * @param courseId 课程主键
     * @return 结果
     */
    @Override
    public int deleteFsUserCourseByCourseId(Long courseId)
    {
        return fsUserCourseMapper.deleteFsUserCourseByCourseId(courseId);
    }


    @Override
    public FsUserCourseUVO selectFsUserCourseUVOByCourseId(Long courseId) {
        FsUserCourseUVO vo = fsUserCourseMapper.selectFsUserCourseUVOByCourseId(courseId);
        vo.setNoteNum(fsUserCourseNoteMapper.selectFsUserCourseNoteCountByCourseId(courseId));
        vo.setCommentNum(fsUserCourseCommentMapper.selectCommentNumByCourseId(courseId));
        vo.setCommentList(fsUserCourseCommentMapper.selectFsUserCourseCommentListVOByCourseId(courseId));
//        vo.setTalentAvatar("https://cos.his.cdwjyyh.com/fs/20240528/07ed79115eb747a2a6083e2e6a2cbc6b.jpg");
        FsUserCourseListUParam param = new FsUserCourseListUParam();
        param.setCateId(vo.getCateId());
        param.setIsTui(1);
        List<FsUserCourseListUVO> list= fsUserCourseMapper.selectFsUserCourseListUVO(param);
        Iterator<FsUserCourseListUVO> iterator = list.iterator();
        while (iterator.hasNext()) {
            FsUserCourseListUVO course = iterator.next();
            if (course.getCourseId().equals(courseId)) {
                iterator.remove();
            }
        }
        vo.setCourseList(list);
        return vo;
    }


    @Override
    public int updateViews(Long courseId) {
        return fsUserCourseMapper.updateViews(courseId);
    }

    @Override
    public int updateShares(Long courseId) {
        return fsUserCourseMapper.updateShares(courseId);
    }

    @Override
    public int updateLikes(Long courseId, Integer type) {
        if (type == 1){
            return fsUserCourseMapper.addLikes(courseId);
        }else {
            return fsUserCourseMapper.minusLikes(courseId);
        }
    }

    @Override
    public int updateFavorite(Long courseId, Integer type) {
        if (type == 1){
            return fsUserCourseMapper.addFavorite(courseId);
        }else {
            return fsUserCourseMapper.minusFavorite(courseId);
        }
    }

    @Override
    public List<FsUserCourseListUVO> selectFsUserCourseListUVO(FsUserCourseListUParam param) {
        return fsUserCourseMapper.selectFsUserCourseListUVO(param);
    }

    @Override
    public List<FsUserCourseListUVO> selectFsUserCourseCommentListUVO(FsUserCourseListUParam param) {
        return fsUserCourseMapper.selectFsUserCourseCommentListUVO(param);
    }

    @Override
    public List<OptionsVO> selectFsUserCourseAllList() {
        return fsUserCourseMapper.selectFsUserCourseAllList();
    }


    @Override
    public List<FsUserCourseListPVO> selectFsUserCourseListPVO(FsUserCourse param) {
        return fsUserCourseMapper.selectFsUserCourseListPVO(param);
    }

    @Override
    public int updateDuration(FsUserCourseAddStudyCourseParam param) {
        return fsUserCourseMapper.updateDuration(param);
    }

    @Override
    public int updateFsUserCourseIsShow(Long[] courseIds, int status) {
        return fsUserCourseMapper.updateFsUserCourseIsShow(courseIds,status);
    }

    @Override
    @Transactional
    public R addStudyCourse(FsUserCourseAddStudyCourseParam param) {
        FsUserCourseVideo courseVideo = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());

        if (courseVideo == null) {
            return R.error("视频不存在");
        }

        FsUserCourse course = fsUserCourseMapper.selectFsUserCourseByCourseId(param.getCourseId());
        if (course == null) {
            return R.error("课堂不存在");
        }

        if (param.getDuration()>=600){
            fsUserNewTaskService.performTaskTwo(param.getUserId());
        }
        FsUserCourseStudyLog log = getOrCreateStudyLog(param, course, courseVideo);

        FsUserCourseStudy courseStudy = fsUserCourseStudyMapper.selectFsUserCourseStudyByAddStudy(param.getUserId(), param.getCourseId());

        if (courseStudy == null) {
            courseStudy = createStudyRecord(param);
            log.setStudyId(courseStudy.getStudyId());
            fsUserCourseStudyLogMapper.insertFsUserCourseStudyLog(log);
        } else {
            log.setStudyId(courseStudy.getStudyId());
            if (log.getLogId() == null) {
                fsUserCourseStudyLogMapper.insertFsUserCourseStudyLog(log);
            } else {
                fsUserCourseStudyLogMapper.updateFsUserCourseStudyLog(log);
            }
        }
        updateDuration(param);
        Long studyCount = fsUserCourseStudyLogMapper.selectStudyLogFinishCount(param.getCourseId(),param.getUserId());
        courseStudy.setPeriodStudy(studyCount);
        if (studyCount.equals(courseStudy.getPeriodTotal())){
            courseStudy.setStatus(3);
        }
        fsUserCourseStudyMapper.updateFsUserCourseStudy(courseStudy);
        return R.ok();
    }

    @Override
    @Transactional
    public R getIntegralByCourseVideo(FsUserCourseGetIntegralParam param) {
        FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
        if (video == null) {
            return R.error("视频不存在");
        }
        FsUserCourse course = fsUserCourseMapper.selectFsUserCourseByCourseId(video.getCourseId());
        if (course==null || course.getIsShow()==0){
            return R.error("课程不存在");
        }
        FsUser user = fsUserMapper.selectFsUserByUserId(param.getUserId());
        if (user==null){
            return R.error("用户不存在");
        }
        String json =configService.selectConfigByKey("his.integral");
        IntegralConfig config= JSONUtil.toBean(json,IntegralConfig.class);
        Integer todayTotalIntegral= fsUserIntegralLogsMapper.selectTodayTotalIntegral(config.getIntegralTypeByOneDay(),param.getUserId());
        if (todayTotalIntegral==null){
            todayTotalIntegral=0;
        }
        if (todayTotalIntegral>=config.getIntegralByOneDay()){
            return R.error("当天芳华币已达限额");
        }
        int rate = (int)((double)param.getDuration() / video.getDuration() * 100);
        if (rate>=50){
            FsUserIntegralLogs integralLogs = fsUserIntegralLogsMapper.selectFsUserIntegralByCourseVideo(param.getVideoId(),param.getUserId());
            if (integralLogs!=null){
                return R.error("该用户已获取此小节积分");
            }
            FsUser userMap = new FsUser();
            userMap.setIntegral(user.getIntegral()+config.getIntegralCourse());
            userMap.setUserId(user.getUserId());
            fsUserMapper.updateFsUser(userMap);
            integralLogs = new FsUserIntegralLogs();
            //写入日志
            integralLogs.setIntegral(config.getIntegralCourse().longValue());
            integralLogs.setUserId(param.getUserId());
            integralLogs.setBalance(userMap.getIntegral());
            integralLogs.setLogType(10);
            integralLogs.setBusinessId(video.getVideoId().toString());
            integralLogs.setCreateTime(new Date());
            fsUserIntegralLogsMapper.insertFsUserIntegralLogs(integralLogs);
            return R.ok("恭喜您获得"+config.getIntegralCourse()+"芳华币");
        }
        return R.error("观看进度不满百分之五十");
    }

    private FsUserCourseStudyLog getOrCreateStudyLog(FsUserCourseAddStudyCourseParam param, FsUserCourse course, FsUserCourseVideo courseVideo) {
        FsUserCourseStudyLog log = fsUserCourseStudyLogMapper.selectFsUserCourseStudyLogByVideo(param.getUserId(), param.getVideoId());
        if (log != null) {
            log.setTotalTimes(log.getTotalTimes()+param.getDuration());
            updateRate(log,param.getDuration(),log.getTimes());
            log.setCreateTime(new Date());
        } else {
            log = new FsUserCourseStudyLog();
            log.setUserId(param.getUserId());
            log.setCourseId(param.getCourseId());
            log.setCourseName(course.getCourseName());
            log.setVideoName(courseVideo.getTitle());
            log.setVideoId(param.getVideoId());
            log.setCurrentTimes(param.getDuration());
            log.setTimes(courseVideo.getDuration());
            log.setCreateTime(new Date());
            log.setTotalTimes(param.getDuration());
            updateRate(log, param.getDuration(), courseVideo.getDuration());
        }
        return log;
    }

    private void updateRate(FsUserCourseStudyLog log, Long currentTimes, Long totalTimes) {
        if (currentTimes <= totalTimes) {
            short rate = (short) ((double) currentTimes / totalTimes * 100);
            log.setRate(rate);
            if (rate>=90){
                log.setStatus(1);
            }
        } else {
            log.setCurrentTimes(totalTimes);
            log.setRate((short) 100);
            log.setStatus(1);
        }
    }

    private FsUserCourseStudy createStudyRecord(FsUserCourseAddStudyCourseParam param) {
        Long videoCount = fsUserCourseVideoMapper.selectVideoCountByCourseId(param.getCourseId());
        FsUserCourseStudy studyMap = new FsUserCourseStudy();
        studyMap.setPeriodTotal(videoCount);
        studyMap.setUserId(param.getUserId());
        studyMap.setCourseId(param.getCourseId());
        studyMap.setCreateTime(new Date());
        studyMap.setStatus(2);
        fsUserCourseStudyMapper.insertFsUserCourseStudy(studyMap);
        return studyMap;
    }

    @Override
    public FsUserCourseVideoH5VO selectFsUserCourseVideoH5VOByVideoId(Long videoId) {
        return fsUserCourseMapper.selectFsUserCourseVideoH5VOByVideoId(videoId);
    }

    @Override
    public FsUserCourseVideoH5DVO selectFsUserCourseVideoH5DVOByVideoId(Long videoId) {
        return fsUserCourseMapper.selectFsUserCourseVideoH5DVOByVideoId(videoId);
    }

    @Override
    public List<FsUserCourseListPVO> selectFsUserCourseListCompanyPVO(FsUserCourseParam fsUserCourse) {
        return fsUserCourseMapper.selectFsUserCourseListCompanyPVO(fsUserCourse);
    }

    @Override
    public List<FsUserCourseListVO> getFsUserCourseList(FsUserCourseListParam param) {
        return fsUserCourseMapper.getFsUserCourseList(param);
    }
}
