package com.yida.data.school.secondClass.service.impl;

import cc.mrbird.febs.common.redis.service.RedisService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.http.HtmlUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yida.data.common.core.entity.constant.CachePrefixConstant;
import com.yida.data.common.core.entity.school.secondClass.EduSecondClassCourse;
import com.yida.data.common.core.entity.school.secondClass.EduSecondClassCourseContent;
import com.yida.data.common.core.entity.school.secondClass.EduSecondClassSubject.TopicType;
import com.yida.data.common.core.vo.NameValueVO;
import com.yida.data.school.dto.secondClass.ListCourseDTO;
import com.yida.data.school.secondClass.mapper.EduSecondClassCourseContentMapper;
import com.yida.data.school.secondClass.mapper.EduSecondClassCourseMapper;
import com.yida.data.school.secondClass.mapper.EduSecondClassSubjectMapper;
import com.yida.data.school.secondClass.service.EduSecondClassCourseService;
import com.yida.data.school.vo.secondClass.CourseH5ContentVO;
import com.yida.data.school.vo.secondClass.CourseH5DetailVO;
import com.yida.data.school.vo.secondClass.CourseVO;
import com.yida.data.school.vo.secondClass.SubjectVO;
import com.yida.data.school.vo.secondClass.VenueVO;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.elasticsearch.search.aggregations.bucket.geogrid.ParsedGeoTileGrid;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * Service实现
 *
 * @author zhanghaijun
 * @date 2022-04-11 11:09:15
 */
@Service
@RequiredArgsConstructor
public class EduSecondClassCourseServiceImpl extends ServiceImpl
    <EduSecondClassCourseMapper, EduSecondClassCourse> implements EduSecondClassCourseService {

    private final EduSecondClassSubjectMapper eduSecondClassSubjectMapper;
    private final EduSecondClassCourseContentMapper eduSecondClassCourseContentMapper;
    private final RedisService redisService;
    private static ExecutorService COURSE_VISIT = new ThreadPoolExecutor(1, 1,
        0L, TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<Runnable>(), ThreadUtil.newNamedThreadFactory("second-class-course-visit", false));

    @Override
    public IPage<CourseVO> listCoursePage(ListCourseDTO dto) {
        Page<CourseVO> page = dto.toPage();
        page.setRecords(baseMapper.listCourse(page, dto));
        if (page.getSize() > 0) {
            for (CourseVO record : page.getRecords()) {
                String remark = HtmlUtil.cleanHtmlTag(record.getRemark());
                record.setRemark(remark.substring(0, Math.min(remark.length(), 50)));
            }
        }
        return page;
    }

    @Override
    @Transactional
    public void delCourse(Long id) {
        eduSecondClassCourseContentMapper
            .delete(Wrappers.<EduSecondClassCourseContent>lambdaQuery().eq(EduSecondClassCourseContent::getCourseId, id));
        removeById(id);
    }

    @Override
    public void changeStatus(Long id, Integer status, Long subjectId) {
        EduSecondClassCourse course = new EduSecondClassCourse();
        course.setId(id);
        course.setStatus(status);
        course.setSubjectId(subjectId);
        updateById(course);
    }

    @Override
    public void changeRecommend(Long id, Integer status) {
        EduSecondClassCourse course = new EduSecondClassCourse();
        course.setId(id);
        course.setHomeRecommend(status);
        updateById(course);
    }

    @Override
    public CourseVO getInfo(Long id) {
        return baseMapper.getInfo(id);
    }

    @Override
    public CourseH5ContentVO getHomeInfo(Long deptId) {
        CourseH5ContentVO vo = new CourseH5ContentVO();
        List<SubjectVO> sujectList = eduSecondClassSubjectMapper.listSubject(TopicType.COURSE.getValue(),null, deptId);
        vo.setSubjectList(sujectList);
        if (CollUtil.isNotEmpty(sujectList)) {
            List<List<CourseVO>> subjectContentList = new ArrayList<>();
            // 查询所有推荐数据 进行填充
            ListCourseDTO dto = new ListCourseDTO();
            dto.setDeptId(deptId);
            dto.setHomeRecommed(1);
            dto.setStatus(1);
            List<CourseVO> courseList = baseMapper
                .listCourse(null, dto);
            Map<Long, List<CourseVO>> courseGroup = courseList.stream().collect(Collectors.groupingBy(CourseVO::getSubjectId));
            for (SubjectVO subject : sujectList) {
                List<CourseVO> subjecrCourseList = null;
                if (subject.getType() == 0) {
                    // 普通信息流数据
                    if (CollUtil.isNotEmpty(courseList)) {
                        for (Entry<Long, List<CourseVO>> entry : courseGroup.entrySet()) {
                            if (entry.getKey().equals(subject.getId())) {
                                subjecrCourseList = entry.getValue();
                            }
                        }
                    }
                } else {
                    // 排行榜数据
                    dto.setHomeRecommed(null);
                    dto.setSortType(1);
                    subjecrCourseList = baseMapper.listCourse(null, dto);
                }
                subjectContentList.add(subjecrCourseList);
            }
            vo.setSubjectContentList(subjectContentList);
        }
        return vo;
    }

    @Override
    public CourseH5DetailVO getCourseDetail(Long id) {
        // 播放量加一
        redisService.incr(CachePrefixConstant.SECOND_CLASS_COURSE_VISIT + id, 1L);
        COURSE_VISIT.execute(() -> baseMapper.incrVisitNum(id));
        return baseMapper.getCourseDetail(id);
    }

    @Override
    public IPage<CourseVO> listCoursePageBySubject(Integer pageNum, Integer pageSize, Long subjectId, Long deptId) {
        return deptId != null ? baseMapper.listCoursePageBySubject(Page.of(pageNum, pageSize), subjectId, deptId)
            : Page.of(pageNum, pageSize);
    }
}
