package com.xinelu.manage.service.trainingitem.Impl;


import com.xinelu.common.config.XinELuConfig;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.enums.TrainingItemTypeEnum;
import com.xinelu.common.enums.TrainingShelfFlagEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.codes.GenerateSystemCodeUtil;
import com.xinelu.common.utils.file.FileUtils;
import com.xinelu.manage.domain.trainingitem.TrainingItem;
import com.xinelu.manage.domain.trainingitemdirectory.TrainingItemDirectory;
import com.xinelu.manage.dto.trainingitem.TrainingItemAndDirectory;
import com.xinelu.manage.mapper.trainingitem.TrainingItemMapper;
import com.xinelu.manage.mapper.trainingitemdirectory.TrainingItemDirectoryMapper;
import com.xinelu.manage.service.trainingitem.ITrainingItemService;
import com.xinelu.manage.vo.trainingitem.TrainingItemAndCategoryVO;
import com.xinelu.manage.vo.trainingitemdirectory.TrainingItemDirectoryVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * 学习培训项目信息Service业务层处理
 *
 * @author xinyilu
 * @date 2023-04-20
 */
@Slf4j
@Service
public class TrainingItemServiceImpl implements ITrainingItemService {
    @Resource
    private TrainingItemMapper trainingItemMapper;
    @Resource
    private TrainingItemDirectoryMapper trainingItemDirectoryMapper;
    @Resource
    private GenerateSystemCodeUtil generateSystemCodeUtil;
    @Resource
    private XinELuConfig xinYiLuConfig;

    /**
     * 查询学习培训项目信息
     *
     * @param id 学习培训项目信息主键
     * @return 学习培训项目信息
     */
    @Override
    public TrainingItemAndDirectory selectTrainingItemById(Long id) {
        return trainingItemMapper.selectTrainingItemAndDirectoryById(id);
    }

    /**
     * 查询学习培训项目信息列表
     *
     * @param trainingItem 学习培训项目信息
     * @return 学习培训项目信息
     */
    @Override
    public List<TrainingItemAndCategoryVO> selectTrainingItemList(TrainingItem trainingItem) {
        trainingItem.setTrainingParentId(Constants.TRAINING_PARENT_ID);
        return trainingItemMapper.selectTrainingItemAndCategoryList(trainingItem);
    }

    /**
     * 新增学习培训项目信息
     *
     * @param trainingItem 学习培训项目信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertTrainingItem(TrainingItemAndDirectory trainingItem) {
        if (Objects.nonNull(trainingItem.getTrainingItemPrice()) && trainingItem.getTrainingItemPrice().compareTo(BigDecimal.ZERO) <= 0) {
            return AjaxResult.error("价格不能为负数或零！");
        }
        if (Objects.nonNull(trainingItem.getTrainingItemSort()) && trainingItem.getTrainingItemSort() <= 0) {
            return AjaxResult.error("排序不能为负数或零！");
        }
        trainingItem.setCreateBy(SecurityUtils.getUsername());
        trainingItem.setCreateTime(LocalDateTime.now());
        trainingItem.setTrainingItemCode(Constants.TRAINING_ITEM + generateSystemCodeUtil.generateSystemCode(Constants.TRAINING_ITEM));
        if (Objects.isNull(trainingItem.getTrainingParentId()) || TrainingItemTypeEnum.LEARNING_ITEM_GROUP.getInfo().equals(trainingItem.getTrainingItemType())) {
            trainingItem.setTrainingParentId(Constants.TRAINING_PARENT_ID);
        }
        trainingItem.setTrainingShelfFlag(TrainingShelfFlagEnum.NOT_SHEL.getInfo());
        int insertTrainingItem = trainingItemMapper.insertTrainingItem(trainingItem);
        if (insertTrainingItem <= 0) {
            throw new ServiceException("新增学习培训课程信息失败，请联系管理员！");
        }
        //新增章节视频
        if (!TrainingItemTypeEnum.VIDEO_LEARNING.getInfo().equals(trainingItem.getTrainingItemType())) {
            return AjaxResult.success();
        }
        if (TrainingItemTypeEnum.VIDEO_LEARNING.getInfo().equals(trainingItem.getTrainingItemType()) && CollectionUtils.isEmpty(trainingItem.getTrainingItemDirectoryList())) {
            throw new ServiceException("请添加章节视频信息！");
        }
        for (TrainingItemDirectory trainingItemDirectory : trainingItem.getTrainingItemDirectoryList()) {
            trainingItemDirectory.setTrainingItemId(Objects.isNull(trainingItem.getId()) ? null : trainingItem.getId());
            if (StringUtils.isBlank(trainingItemDirectory.getItemDirectoryUrl())) {
                throw new ServiceException("请添加章节视频信息！");
            }
            if (StringUtils.isNotBlank(trainingItemDirectory.getItemDirectoryUrl())) {
                trainingItemDirectory.setItemDirectoryVideoDuration(FileUtils.getVideoDuration(trainingItemDirectory.getItemDirectoryUrl().replaceAll(Constants.D_RESOURCE_PREFIX, Constants.D_UPLOAD_PREFIX)));
            }
            if (Objects.nonNull(trainingItemDirectory.getItemDirectorySort()) && trainingItemDirectory.getItemDirectorySort() <= 0) {
                throw new ServiceException("排序不能为负数或零！");
            }
            trainingItemDirectory.setItemDirectoryCode(Constants.TRAINING_ITEM_DIRECTORY + generateSystemCodeUtil.generateSystemCode(Constants.TRAINING_ITEM_DIRECTORY));
        }
        int count = trainingItemDirectoryMapper.insertTrainingItemDirectoryList(trainingItem.getTrainingItemDirectoryList());
        if (count <= 0) {
            throw new ServiceException("新增章节视频信息失败，请联系管理员！");
        }
        return AjaxResult.success();
    }

    /**
     * 修改学习培训项目信息
     *
     * @param trainingItem 学习培训项目信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateTrainingItem(TrainingItemAndDirectory trainingItem) {
        if (Objects.isNull(trainingItem.getTrainingItemId())) {
            return AjaxResult.error("学习培训课程信息不能为空！");
        }
        if (Objects.nonNull(trainingItem.getTrainingItemPrice()) && trainingItem.getTrainingItemPrice().compareTo(BigDecimal.ZERO) <= 0) {
            return AjaxResult.error("价格不能为负数或零！");
        }
        if (Objects.nonNull(trainingItem.getTrainingItemSort()) && trainingItem.getTrainingItemSort() <= 0) {
            return AjaxResult.error("排序不能为负数或零！");
        }
        if (Objects.nonNull(trainingItem.getTrainingParentId()) && trainingItem.getTrainingParentId().equals(trainingItem.getTrainingItemId())) {
            return AjaxResult.error("父级项目与本项目有冲突！请选择其他父级项目！");
        }
        //查询数据库信息
        TrainingItemAndDirectory trainingItemAndDirectory = trainingItemMapper.selectTrainingItemAndDirectoryById(trainingItem.getTrainingItemId());
        trainingItem.setUpdateBy(SecurityUtils.getUsername());
        trainingItem.setUpdateTime(LocalDateTime.now());
        trainingItem.setId(trainingItem.getTrainingItemId());
        if (Objects.isNull(trainingItem.getTrainingParentId()) || TrainingItemTypeEnum.LEARNING_ITEM_GROUP.getInfo().equals(trainingItem.getTrainingItemType())) {
            trainingItem.setTrainingParentId(Constants.TRAINING_PARENT_ID);
        }
        int updateTrainingItem = trainingItemMapper.updateTrainingItems(trainingItem);
        if (updateTrainingItem <= 0) {
            throw new ServiceException("修改培训课程信息失败，请联系管理员！");
        }
        //新增章节视频
        if (!TrainingItemTypeEnum.VIDEO_LEARNING.getInfo().equals(trainingItem.getTrainingItemType())) {
            //富文本修改
            if (StringUtils.isNotBlank(trainingItemAndDirectory.getTrainingItemContent()) && StringUtils.isNotBlank(trainingItem.getTrainingItemContent()) && !trainingItemAndDirectory.getTrainingItemContent().equals(trainingItem.getTrainingItemContent())) {
                FileUtils.deleteTextUrl(trainingItemAndDirectory.getTrainingItemContent(), trainingItem.getTrainingItemContent());
            }
            return AjaxResult.success();
        }
        if (TrainingItemTypeEnum.VIDEO_LEARNING.getInfo().equals(trainingItem.getTrainingItemType()) && CollectionUtils.isEmpty(trainingItem.getTrainingItemDirectoryList())) {
            throw new ServiceException("请添加章节视频信息！");
        }
        //修改章节
        updateTrainingItemDirectory(trainingItemAndDirectory, trainingItem);
        //富文本修改
        if (StringUtils.isNotBlank(trainingItemAndDirectory.getTrainingItemContent()) && StringUtils.isNotBlank(trainingItem.getTrainingItemContent()) && !trainingItemAndDirectory.getTrainingItemContent().equals(trainingItem.getTrainingItemContent())) {
            FileUtils.deleteTextUrl(trainingItemAndDirectory.getTrainingItemContent(), trainingItem.getTrainingItemContent());
        }
        return AjaxResult.success();
    }

    /**
     * 批量删除学习培训项目信息
     *
     * @param ids 需要删除的学习培训项目信息主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult deleteTrainingItemByIds(Long[] ids) {
        //查询数据库信息
        List<TrainingItemAndDirectory> trainingItemAndDirectories = trainingItemMapper.selectTrainingItemAndDirectoryList(ids, null);
        if (CollectionUtils.isEmpty(trainingItemAndDirectories)) {
            return AjaxResult.success();
        }
        List<TrainingItemAndDirectory> childTrainingItemAndDirectories = trainingItemMapper.selectTrainingItemAndDirectoryList(null, ids);
        if (CollectionUtils.isEmpty(childTrainingItemAndDirectories) && CollectionUtils.isEmpty(trainingItemAndDirectories)) {
            return AjaxResult.success();
        }
        List<Long> dataList = Lists.newArrayList();
        List<Long> childIdsList = childTrainingItemAndDirectories.stream().filter(Objects::nonNull).map(TrainingItemAndDirectory::getTrainingItemId).filter(Objects::nonNull).collect(Collectors.toList()).stream().filter(Objects::nonNull).collect(Collectors.toList());
        dataList.addAll(Arrays.asList(ids));
        dataList.addAll(childIdsList);
        int count = trainingItemMapper.deleteTrainingItemByIds(dataList);
        if (count <= 0) {
            throw new ServiceException("删除信息失败，请联系管理员！");
        }
        //删除章节
        deleteTrainingItemDirectory(trainingItemAndDirectories);
        if (CollectionUtils.isNotEmpty(childTrainingItemAndDirectories)) {
            deleteTrainingItemDirectory(childTrainingItemAndDirectories);
        }
        //删除图片视频
        deleteUrl(trainingItemAndDirectories);
        if (CollectionUtils.isNotEmpty(childTrainingItemAndDirectories)) {
            deleteUrl(childTrainingItemAndDirectories);
        }
        return AjaxResult.success();
    }

    /**
     * 上传文件
     *
     * @param multipartFile 文件
     * @return AjaxResult
     * @throws Exception 错误信息
     */
    @Override
    public AjaxResult uploadUrl(MultipartFile multipartFile, String type) throws Exception {
        //获取不同的文件路径
        String uploadPathUrl = "";
        if (Constants.TRAINING_ITEM_COVER_URL.equals(type)) {
            uploadPathUrl = XinELuConfig.getProfile() + xinYiLuConfig.getTrainingItemCoverUrl();
        }
        if (Constants.TRAINING_ITEM_POSTER_URL.equals(type)) {
            uploadPathUrl = XinELuConfig.getProfile() + xinYiLuConfig.getTrainingItemPosterUrl();
        }
        if (StringUtils.isEmpty(uploadPathUrl)) {
            return AjaxResult.success();
        }
        return FileUtils.uploadImages(uploadPathUrl, multipartFile);
    }

    /**
     * 上传文件
     *
     * @param multipartFile 文件
     * @return AjaxResult
     * @throws Exception 错误信息
     */
    @Override
    public AjaxResult uploadVideoUrl(MultipartFile multipartFile) throws Exception {
        if (Objects.isNull(multipartFile) || StringUtils.isBlank(multipartFile.getOriginalFilename())) {
            return AjaxResult.error("当前文件视频不存在，无法上传！");
        }
        if (multipartFile.getOriginalFilename().contains(Constants.EMPTY)) {
            return AjaxResult.error("当前视频文件名含有空格，请先去除空格在上传！");
        }
        String uploadPathUrl = XinELuConfig.getProfile() + xinYiLuConfig.getItemDirectoryUrl();
        return FileUtils.uploadVideo(uploadPathUrl, multipartFile);
    }

    /**
     * 查询父级项目列表
     *
     * @param trainingItem 信息
     * @return AjaxResult
     */
    @Override
    public List<TrainingItemAndCategoryVO> selectTrainingParent(TrainingItemAndDirectory trainingItem) {
        trainingItem.setTrainingItemType(TrainingItemTypeEnum.LEARNING_ITEM_GROUP.getInfo());
        return trainingItemMapper.selectTrainingItems(trainingItem);
    }

    /**
     * 修改上下架状态
     *
     * @param trainingItem 学习培训项目信息
     * @return AjaxResult
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateTrainingShelfFlag(TrainingItem trainingItem) {
        //修改本级状态
        int updateTrainingItem = trainingItemMapper.updateTrainingItem(trainingItem);
        if (updateTrainingItem <= 0) {
            log.error("修改学习培训课程组信息失败，学习培训课程组id为：{}", trainingItem.getId());
            throw new ServiceException("修改上下架状态失败！");
        }
        //修改下级状态
        if (StringUtils.isNotBlank(trainingItem.getTrainingItemType()) && TrainingItemTypeEnum.LEARNING_ITEM_GROUP.getInfo().equals(trainingItem.getTrainingItemType())) {
            trainingItem.setTrainingParentId(trainingItem.getId());
            int count = trainingItemMapper.updateTrainingItemList(trainingItem);
            if (count < 0) {
                log.error("修改学习培训视频课程信息失败，所属课程组id为：{}", trainingItem.getId());
                throw new ServiceException("修改上下架状态失败！");
            }
        }
        return AjaxResult.success();
    }

    /**
     * 查询下级项目
     *
     * @param trainingItem 父级id
     * @return AjaxResult
     */
    @Override
    public AjaxResult selectSubordinateItem(TrainingItem trainingItem) {
        return AjaxResult.success(trainingItemMapper.selectTrainingItemAndCategoryList(trainingItem));
    }

    /**
     * 修改章节信息
     *
     * @param trainingItemAndDirectory 数据库数据库信息
     * @param trainingItem             前端传入
     */
    private void updateTrainingItemDirectory(TrainingItemAndDirectory trainingItemAndDirectory, TrainingItemAndDirectory trainingItem) {
        List<Long> databaseDirectoryIds = trainingItemAndDirectory.getTrainingItemDirectoryList().stream().filter(Objects::nonNull).map(TrainingItemDirectoryVO::getTrainingItemDirectoryId).filter(Objects::nonNull).collect(Collectors.toList());
        List<Long> afferentDirectoryIds = trainingItem.getTrainingItemDirectoryList().stream().filter(Objects::nonNull).map(TrainingItemDirectoryVO::getTrainingItemDirectoryId).filter(Objects::nonNull).collect(Collectors.toList());
        List<String> itemDirectoryUrlList = trainingItemAndDirectory.getTrainingItemDirectoryList().stream().filter(Objects::nonNull).map(TrainingItemDirectory::getItemDirectoryUrl).filter(StringUtils::isNotBlank).collect(Collectors.toList());
        List<String> afferentUrlList = trainingItem.getTrainingItemDirectoryList().stream().filter(Objects::nonNull).map(TrainingItemDirectory::getItemDirectoryUrl).filter(StringUtils::isNotBlank).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(afferentUrlList)) {
            throw new ServiceException("请添加章节视频信息！");
        }
        //databaseDirectoryIds减afferentDirectoryIds,删除
        List<Long> subtractIds = new ArrayList<>(CollectionUtils.subtract(databaseDirectoryIds, afferentDirectoryIds));
        if (CollectionUtils.isNotEmpty(subtractIds)) {
            Long[] longs = subtractIds.stream().filter(Objects::nonNull).toArray(Long[]::new);
            int deleteCount = trainingItemDirectoryMapper.deleteTrainingItemDirectoryByIds(longs);
            if (deleteCount <= 0) {
                log.error("删除章节信息失败!");
                throw new ServiceException("修改培训课程信息失败，请联系管理员！");
            }
        }
        //id为空新增
        List<TrainingItemDirectoryVO> trainingItemDirectoryList = new ArrayList<>();
        for (TrainingItemDirectoryVO trainingItemDirectory : trainingItem.getTrainingItemDirectoryList()) {
            if (StringUtils.isBlank(trainingItemDirectory.getItemDirectoryTitle()) && StringUtils.isBlank(trainingItemDirectory.getItemDirectoryName()) && StringUtils.isBlank(trainingItemDirectory.getItemDirectoryUrl()) && StringUtils.isBlank(trainingItemDirectory.getItemDirectoryIntroduce())) {
                continue;
            }
            if (StringUtils.isBlank(trainingItemDirectory.getItemDirectoryTitle()) || StringUtils.isBlank(trainingItemDirectory.getItemDirectoryName()) || StringUtils.isBlank(trainingItemDirectory.getItemDirectoryUrl()) || StringUtils.isBlank(trainingItemDirectory.getItemDirectoryIntroduce())) {
                throw new ServiceException("请添加章节视频信息！");
            }
            if (Objects.nonNull(trainingItemDirectory.getItemDirectoryUrl())) {
                trainingItemDirectory.setItemDirectoryVideoDuration(FileUtils.getVideoDuration(trainingItemDirectory.getItemDirectoryUrl().replaceAll(Constants.D_RESOURCE_PREFIX, Constants.D_UPLOAD_PREFIX)));
            }
            if (Objects.isNull(trainingItemDirectory.getTrainingItemDirectoryId())) {
                trainingItemDirectory.setTrainingItemId(trainingItem.getId());
                trainingItemDirectory.setItemDirectoryCode(Constants.TRAINING_ITEM_DIRECTORY + generateSystemCodeUtil.generateSystemCode(Constants.TRAINING_ITEM_DIRECTORY));
                trainingItemDirectoryList.add(trainingItemDirectory);
            }
            //不为空修改
            if (Objects.nonNull(trainingItemDirectory.getTrainingItemDirectoryId())) {
                trainingItemDirectory.setId(trainingItemDirectory.getTrainingItemDirectoryId());
                trainingItemDirectoryMapper.updateTrainingItemDirectory(trainingItemDirectory);
            }
        }
        if (CollectionUtils.isNotEmpty(trainingItemDirectoryList)) {
            int insertDirectoryCount = trainingItemDirectoryMapper.insertTrainingItemDirectoryList(trainingItemDirectoryList);
            if (insertDirectoryCount <= 0) {
                log.error("新增项目章节信息失败！");
                throw new ServiceException("修改培训课程信息失败，请联系管理员！");
            }
        }
        List<String> subtractUrl = new ArrayList<>(CollectionUtils.subtract(itemDirectoryUrlList, afferentUrlList));
        for (String itemDirectoryUrl : subtractUrl) {
            FileUtils.deleteSystemFile(itemDirectoryUrl);
        }
    }

    /**
     * 删除视频主表
     *
     * @param trainingItemAndDirectories 文件信息
     */
    private void deleteTrainingItemDirectory(List<TrainingItemAndDirectory> trainingItemAndDirectories) {
        List<Long> trainingItemDirectoryIdList = new ArrayList<>();
        for (TrainingItemAndDirectory trainingItemAndDirectory : trainingItemAndDirectories) {
            if (CollectionUtils.isEmpty(trainingItemAndDirectory.getTrainingItemDirectoryList())) {
                continue;
            }
            List<Long> trainingItemDirectoryIds = trainingItemAndDirectory.getTrainingItemDirectoryList().stream().filter(Objects::nonNull).map(TrainingItemDirectoryVO::getTrainingItemDirectoryId).filter(Objects::nonNull).collect(Collectors.toList());
            trainingItemDirectoryIdList.addAll(trainingItemDirectoryIds);
        }
        if (CollectionUtils.isNotEmpty(trainingItemDirectoryIdList)) {
            trainingItemDirectoryMapper.deleteTrainingItemDirectoryByIds(trainingItemDirectoryIdList.toArray(new Long[0]));
        }
    }

    /**
     * 删除图片视频
     *
     * @param trainingItemAndDirectories 文件
     */
    private void deleteUrl(List<TrainingItemAndDirectory> trainingItemAndDirectories) {
        //取出课程信息的封面路径和海报路径
        List<String> trainingItemCoverUrlList = trainingItemAndDirectories.stream().filter(Objects::nonNull).map(TrainingItemAndDirectory::getTrainingItemCoverUrl).filter(StringUtils::isNotBlank).collect(Collectors.toList());
        List<String> trainingItemPosterUrList = trainingItemAndDirectories.stream().filter(Objects::nonNull).map(TrainingItemAndDirectory::getTrainingItemPosterUrl).filter(StringUtils::isNotBlank).collect(Collectors.toList());
        trainingItemCoverUrlList.addAll(trainingItemPosterUrList);
        for (TrainingItemAndDirectory trainingItemAndDirectory : trainingItemAndDirectories) {
            if (CollectionUtils.isEmpty(trainingItemAndDirectory.getTrainingItemDirectoryList())) {
                continue;
            }
            List<String> itemDirectoryUrlList = trainingItemAndDirectory.getTrainingItemDirectoryList().stream().filter(Objects::nonNull).map(TrainingItemDirectory::getItemDirectoryUrl).filter(StringUtils::isNotBlank).collect(Collectors.toList());
            trainingItemCoverUrlList.addAll(itemDirectoryUrlList);
        }
        //删除图片
        if (CollectionUtils.isNotEmpty(trainingItemCoverUrlList)) {
            for (String trainingItemCoverUrl : trainingItemCoverUrlList) {
                FileUtils.deleteSystemFile(trainingItemCoverUrl);
            }
        }
        //富文本删除
        List<String> trainingItemContentList = trainingItemAndDirectories.stream().filter(Objects::nonNull).map(TrainingItem::getTrainingItemContent).filter(StringUtils::isNotBlank).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(trainingItemContentList)) {
            for (String trainingItemContent : trainingItemContentList) {
                FileUtils.deleteTextUrl(trainingItemContent, null);
            }
        }
    }
}