package cn.iocoder.byzs.module.bjdx.service.course;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.byzs.framework.common.pojo.PageResult;
import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
import cn.iocoder.byzs.module.bjdx.controller.admin.course.vo.CoursePageReqVO;
import cn.iocoder.byzs.module.bjdx.controller.admin.course.vo.CourseRespVO;
import cn.iocoder.byzs.module.bjdx.controller.admin.course.vo.CourseSaveReqVO;
import cn.iocoder.byzs.module.bjdx.dal.dataobject.course.CourseDO;
import cn.iocoder.byzs.module.bjdx.dal.mysql.course.CourseMapper;
import cn.iocoder.byzs.module.infra.dal.dataobject.file.FileDO;
import cn.iocoder.byzs.module.infra.framework.file.core.client.FileClient;
import cn.iocoder.byzs.module.infra.service.file.FileConfigService;
import cn.iocoder.byzs.module.infra.service.file.FileServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.List;
import java.util.stream.Collectors;

import static cn.iocoder.byzs.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.byzs.module.bjdx.enums.ErrorCodeConstants.COURSE_NOT_EXISTS;

/**
 * 课程 Service 实现类
 *
 * @author lyb
 */
@Service
@Validated
public class CourseServiceImpl implements CourseService {

    @Resource
    private CourseMapper courseMapper;
    @Resource
    private FileServiceImpl fileService;
    @Resource
    private FileConfigService fileConfigService;

    @Override
    public Long createCourse(CourseSaveReqVO createReqVO) {
        // 插入
        CourseDO course = BeanUtils.toBean(createReqVO, CourseDO.class);
        courseMapper.insert(course);

        if (course.getCourseContentType().equals("video")) {
            getSelf().asymcVideoFfmpeg(course);
        }
        // 返回
        return course.getId();
    }

    @Override
    public void updateCourse(CourseSaveReqVO updateReqVO) {
        // 校验存在
        validateCourseExists(updateReqVO.getId());
        // 更新
        CourseDO updateObj = BeanUtils.toBean(updateReqVO, CourseDO.class);
        courseMapper.updateById(updateObj);

        if (updateObj.getCourseContentType().equals("video")) {
            getSelf().asymcVideoFfmpeg(updateObj);
        }
    }

    @Async
    public void asymcVideoFfmpeg(CourseDO course) {
        //只对mp4文件进行处理
        String courseVideoPath = course.getCourseVideoPath();
        String ext = courseVideoPath.substring(courseVideoPath.lastIndexOf("."));
        if (StrUtil.isBlank(ext) || ext.equals(".m3u8")) {
            return;
        }

        //获取相对文件路径
        FileDO fileDO= fileService.getFilePathByUrl(course.getCourseVideoPath());
        if (fileDO == null || fileDO.getPath() == null) {
            return;
        }

        //切片
        FileClient client = fileConfigService.getMasterFileClient();
        String m3u8Path = client.ffmpegHts(fileDO.getPath());
        if(StrUtil.isNotEmpty(m3u8Path)){
            courseMapper.updateById(new CourseDO().setId(course.getId()).setCourseVideoPath(m3u8Path));
            fileDO.setUrl(m3u8Path);
            fileService.updateFileById(fileDO);

            // 从文件存储器中删除【暂时不删除mp4文件，删除时需要同步更改fileDo中path的相对路径更改成m3u8文件】
//            try {
//                client.delete(courseVideoPath);
//            } catch (Exception e) {
//                throw new RuntimeException(e);
//            }
        }
    }

    @Override
    public void deleteCourse(Long id) {
        // 校验存在
        validateCourseExists(id);
        // 删除
        courseMapper.deleteById(id);
    }

    @Override
        public void deleteCourseListByIds(List<Long> ids) {
        // 校验存在
        validateCourseExists(ids);
        // 删除
        courseMapper.deleteByIds(ids);
        }

    private void validateCourseExists(List<Long> ids) {
        List<CourseDO> list = courseMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(COURSE_NOT_EXISTS);
        }
    }

    private void validateCourseExists(Long id) {
        if (courseMapper.selectById(id) == null) {
            throw exception(COURSE_NOT_EXISTS);
        }
    }

    @Override
    public CourseDO getCourse(Long id) {
        return courseMapper.selectById(id);
    }

    @Override
    public PageResult<CourseRespVO> getCoursePage(CoursePageReqVO pageReqVO) {

        List<CoursePageReqVO> coursePageReqVOS = courseMapper.selectCoursePage(pageReqVO);

        // 调用服务层方法获取分页结果
        return new PageResult<>(
                coursePageReqVOS.stream()
                        .map(doItem -> BeanUtils.toBean(doItem, CourseRespVO.class))
                        .collect(Collectors.toList()),
                (long) coursePageReqVOS.size()
        );
    }

    @Override
    public List<CoursePageReqVO> getCourseList(CoursePageReqVO pageReqVO) {
        return courseMapper.selectCoursePage(pageReqVO);
    }


    /**
     * 获得自身的代理对象，解决 AOP 生效问题
     *
     * @return 自己
     */
    private CourseServiceImpl getSelf() {
        return SpringUtil.getBean(getClass());
    }

}