package com.ruoyi.hezhi.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.ServiceResponseEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.hezhi.domain.TbCourse;
import com.ruoyi.hezhi.domain.TbSubjectWarehouseClass;
import com.ruoyi.hezhi.domain.dto.CourseDTO;
import com.ruoyi.hezhi.domain.dto.DelHistoricalRecordsDTO;
import com.ruoyi.hezhi.mapper.TbCourseChapterMapper;
import com.ruoyi.hezhi.mapper.TbCourseMapper;
import com.ruoyi.hezhi.mapper.TbTeacherCourseMapper;
import com.ruoyi.hezhi.service.ITbCourseService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 课程Service业务层处理
 *
 * @author ruoyi
 * @date 2024-09-14
 */
@Service
public class TbCourseServiceImpl implements ITbCourseService
{
    @Autowired
    private TbCourseMapper tbCourseMapper;
    @Autowired
    private TbTeacherCourseMapper tbTeacherCourseMapper;
    @Autowired
    private TbCourseChapterMapper tbCourseChapterMapper;
    @Resource
    private RedisCache redisCache;
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     * 查询课程
     *
     * @param courseId 课程主键
     * @return 课程
     */
    @Override
    public TbCourse selectTbCourseByCourseId(Long courseId)
    {
        return tbCourseMapper.selectTbCourseByCourseId(courseId);
    }

    /**
     * 查询课程列表
     *
     * @param tbCourse 课程
     * @return 课程
     */
    @Override
    public List<TbCourse> selectTbCourseList(TbCourse tbCourse)
    {
        // 机构ID
        if (SecurityUtils.hasRole("evaluateAgency") && !SecurityUtils.isAdmin(SecurityUtils.getUserId())){
            tbCourse.setEvaluateAgencyId(SecurityUtils.getEvaluateAgencyId());
        }
        return tbCourseMapper.selectTbCourseList(tbCourse);
    }

    /**
     * 查询课程列表
     *
     * @return 课程
     */
    @Override
    public List<TbCourse> getAllCourseList()
    {
        return tbCourseMapper.getAllCourseList();
    }

    /**
     * 新增课程
     *
     * @param tbCourse 课程
     * @return 结果
     */
    @Override
    public int insertTbCourse(TbCourse tbCourse)
    {
        // 机构ID
        if (SecurityUtils.hasRole("evaluateAgency") && !SecurityUtils.isAdmin(SecurityUtils.getUserId())){
            tbCourse.setEvaluateAgencyId(SecurityUtils.getEvaluateAgencyId());
        }
        //课程名不能重复
        TbCourse tbCourse1 = tbCourseMapper.selectTbCourseByNameAndEva(tbCourse.getCourseName(),tbCourse.getEvaluateAgencyId());
        if (tbCourse1 != null){
            throw new ServiceException("同一机构下课程名不能重复");
        }
        tbCourse.setCreateTime(DateUtils.getNowDate());
        return tbCourseMapper.insertTbCourse(tbCourse);
    }

    /**
     * 修改课程
     *
     * @param tbCourse 课程
     * @return 结果
     */
    @Override
    public int updateTbCourse(TbCourse tbCourse)
    {
        // 机构ID
        if (SecurityUtils.hasRole("evaluateAgency") && !SecurityUtils.isAdmin(SecurityUtils.getUserId())){
            Long evaluateAgencyId = SecurityUtils.getEvaluateAgencyId();
            TbCourse oldCourse = tbCourseMapper.selectTbCourseByCourseId(tbCourse.getCourseId());
            if (oldCourse.getEvaluateAgencyId() == null || !oldCourse.getEvaluateAgencyId().equals(evaluateAgencyId)){
                throw new ServiceException(ServiceResponseEnum.NO_AUTH_OPERATION);
            }
            tbCourse.setEvaluateAgencyId(evaluateAgencyId);
        }
        tbCourse.setUpdateTime(DateUtils.getNowDate());
        return tbCourseMapper.updateTbCourse(tbCourse);
    }


    /**
     * 修改课程
     *
     * @param tbCourse 课程
     * @return 结果
     */
    @Override
    public int updateTbCourseById(TbCourse tbCourse)
    {
        tbCourse.setUpdateTime(DateUtils.getNowDate());
        return tbCourseMapper.updateTbCourse(tbCourse);
    }

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

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

    /**
     * 查询课程列表
     *
     * @param params 参数
     * @return ok
     */
    @Override
    public List<Map<String, Object>> getCourseList(Map<String, Object> params) {
        return tbCourseMapper.getCourseList(params);
    }

    /**
     * 查询课程详情
     *
     * @param params 参数
     * @return ok
     */
    @Override
    public Map<String, Object> getCourseInfo(Map<String, Object> params) {
        Map<String, Object> courseInfo = tbCourseMapper.getCourseInfo(params);
        if (!courseInfo.isEmpty()) {
            // 主讲老师
            courseInfo.put("teacherList", tbTeacherCourseMapper.getTeacherList(params));
            // 视频列表
            List<Map<String, Object>> chapterList = tbCourseChapterMapper.getCourseChapterList(params);
            courseInfo.put("videoList", chapterList);
            if(chapterList.size() > 0) {
                courseInfo.put("chapterUrl", chapterList.get(0).get("chapterUrl").toString());
            } else {
                courseInfo.put("chapterUrl", "");
            }
        }
        return courseInfo;
    }

    /**
     * 立即参加
     *
     * @param courseDTO
     * @return ok
     */
    @Override
    public AjaxResult joinNow(CourseDTO courseDTO) {
        TbCourse tbCourse = tbCourseMapper.selectTbCourseByCourseId(courseDTO.getCourseId());
        if (tbCourse != null) {
            TbCourse updateCourse = new TbCourse();
            updateCourse.setCourseId(courseDTO.getCourseId());
            updateCourse.setParticipateNum(tbCourse.getParticipateNum() + 1);
            tbCourseMapper.updateTbCourse(updateCourse);
        }
        return AjaxResult.success();
    }

    /**
     * 浏览量+1
     *
     * @param courseId 课程主键
     * @return 结果
     */
    @Override
    public int addViewsNum(Long courseId) {
        return tbCourseMapper.addViewsNum(courseId);
    }

    @Override
    public PageInfo<Map<String, Object>> getCourseNameListForInput(Integer pageNum, Integer pageSize, String searchValue,Long memberUserId){
        PageHelper.startPage(pageNum, pageSize);
        if (StringUtils.isNotNull(memberUserId)&&StringUtils.isNotEmpty(searchValue)){
            threadPoolTaskExecutor.execute(() -> {
                //处理历史记录
                processHistoricalRecords(memberUserId,searchValue);
            });
        }
        List<Map<String, Object>> courseNameListForInput = tbCourseMapper.getCourseNameListForInput(searchValue);
        return new PageInfo<>(courseNameListForInput);
    }

    /**
     * 处理搜索记录
     * @param memberUserId 用户id
     * @param searchValue 搜索值
     */
    private void processHistoricalRecords(Long memberUserId, String searchValue) {
        Boolean b = redisCache.hasKey(CacheConstants.COURSE_SEARCH_HISTORY_KEY + memberUserId);
        if (b){
            //保存历史搜索记录
            List<String> searchHistoryList = redisCache.getCacheObject(CacheConstants.COURSE_SEARCH_HISTORY_KEY + memberUserId);
            searchHistoryList.add(searchValue);
            redisCache.setCacheObject(CacheConstants.COURSE_SEARCH_HISTORY_KEY + memberUserId, searchHistoryList);
        }else {
            List<String> searchHistoryList = new ArrayList<>();
            searchHistoryList.add(searchValue);
            redisCache.setCacheObject(CacheConstants.COURSE_SEARCH_HISTORY_KEY + memberUserId, searchHistoryList);
        }
        //热搜
        Boolean a = redisCache.hasKey(CacheConstants.COURSE_HOT_SEARCH_KEY);
        if (a){
            //保存历史搜索记录
            List<String> searchHistoryList = redisCache.getCacheObject(CacheConstants.COURSE_HOT_SEARCH_KEY);
            searchHistoryList.add(searchValue);
            redisCache.setCacheObject(CacheConstants.COURSE_HOT_SEARCH_KEY, searchHistoryList);
        }else {
            List<String> searchHistoryList = new ArrayList<>();
            searchHistoryList.add(searchValue);
            redisCache.setCacheObject(CacheConstants.COURSE_HOT_SEARCH_KEY, searchHistoryList);
        }
    }

    /**
     * 获取搜索记录
     * @return
     */
    public List<String> getHotSearch(Integer size) {
        if (StringUtils.isNull(size)){
            size=10;
        }
        Boolean b = redisCache.hasKey(CacheConstants.COURSE_HOT_SEARCH_KEY);
        if (!b) {
            return new ArrayList<>();
        }
        List<String> searchHistoryList = redisCache.getCacheObject(CacheConstants.COURSE_HOT_SEARCH_KEY);
        // 计算每个字符串的出现次数
        Map<String, Long> frequencyMap = searchHistoryList.stream()
                .collect(Collectors.groupingBy(s -> s, Collectors.counting()));
        // 根据出现次数从高到低排序，去重后输出按次数排序的字符串
        List<String> sortedList = frequencyMap.entrySet().stream()
                .sorted((entry1, entry2) -> entry2.getValue().compareTo(entry1.getValue())) // 按次数降序排序
                .map(Map.Entry::getKey)  // 提取字符串部分，去掉计数值
                .collect(Collectors.toList());
        if (sortedList.size() > size) {
            sortedList = sortedList.subList(0, size);
        }
        return sortedList;
    }

    /**
     * 搜索历史记录
     * @param memberUserId 用户id
     * @param size 数量
     * @return
     */
    public List<String> getHistoricalRecords(Long memberUserId, Integer size) {
        if (StringUtils.isNull(size)){
            size=10;
        }
        Boolean b = redisCache.hasKey(CacheConstants.COURSE_SEARCH_HISTORY_KEY + memberUserId);
        if (!b){
            return new ArrayList<>();
        }
        List<String> searchHistoryList = redisCache.getCacheObject(CacheConstants.COURSE_SEARCH_HISTORY_KEY + memberUserId);
        Collections.reverse(searchHistoryList);
        searchHistoryList=searchHistoryList.stream().distinct().collect(Collectors.toList());
        if (searchHistoryList.size() > size) {
            searchHistoryList = searchHistoryList.subList(0, size);
        }
        return searchHistoryList;
    }

    /**
     * 删除历史记录
     * @param dto
     * @return
     */
    public int delHistoricalRecords(DelHistoricalRecordsDTO dto) {
        Boolean b = redisCache.hasKey(CacheConstants.COURSE_SEARCH_HISTORY_KEY + dto.getMemberUserId());
        if (!b){
           return 1;
        }
        redisCache.deleteObject(CacheConstants.COURSE_SEARCH_HISTORY_KEY + dto.getMemberUserId());
        return 1;
    }
}
