package com.xinyilu.system.service.motionprescriptionlibrary.Impl;

import com.xinyilu.common.config.XinYiLuConfig;
import com.xinyilu.common.core.domain.AjaxResult;
import com.xinyilu.common.exception.ServiceException;
import com.xinyilu.common.utils.DateUtils;
import com.xinyilu.common.utils.SecurityUtils;
import com.xinyilu.common.utils.file.FileUploadUtils;
import com.xinyilu.common.utils.file.FileUtils;
import com.xinyilu.common.utils.file.MimeTypeUtils;
import com.xinyilu.system.domain.dto.MotionPrescriptionVideoDTO;
import com.xinyilu.system.domain.motionprescriptionlibrary.MotionPrescriptionLibrary;
import com.xinyilu.system.domain.motionprescriptionvideo.MotionPrescriptionVideo;
import com.xinyilu.system.domain.vo.MotionPrescriptionVideoVO;
import com.xinyilu.system.domain.vo.motionprescriptionlibrary.MotionPrescriptionLibraryVO;
import com.xinyilu.system.mapper.motionprescriptionlibrary.MotionPrescriptionLibraryMapper;
import com.xinyilu.system.mapper.motionprescriptionvideo.MotionPrescriptionVideoMapper;
import com.xinyilu.system.service.motionprescriptionlibrary.IMotionPrescriptionLibraryService;
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.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * 运动处方库数据Service业务层处理
 *
 * @author xinyilu
 * @date 2023-04-03
 */
@Slf4j
@Service
public class MotionPrescriptionLibraryServiceImpl implements IMotionPrescriptionLibraryService {
    @Resource
    private MotionPrescriptionLibraryMapper motionPrescriptionLibraryMapper;
    @Resource
    private XinYiLuConfig xinYiLuConfig;
    @Resource
    private MotionPrescriptionVideoMapper motionPrescriptionVideoMapper;

    /**
     * 查询运动处方库数据
     *
     * @param id 运动处方库数据主键
     * @return 运动处方库数据
     */
    @Override
    public MotionPrescriptionLibrary selectMotionPrescriptionLibraryById(Long id) {
        return motionPrescriptionLibraryMapper.selectMotionPrescriptionLibraryById(id);
    }

    /**
     * 查询运动处方库数据列表
     *
     * @param motionPrescriptionLibrary 运动处方库数据
     * @return 运动处方库数据
     */
    @Override
    public List<MotionPrescriptionLibraryVO> selectMotionPrescriptionLibraryList(MotionPrescriptionLibrary motionPrescriptionLibrary) {
        return motionPrescriptionLibraryMapper.selectMotionPrescriptionLibraryList(motionPrescriptionLibrary);
    }

    /**
     * 新增运动处方库数据
     *
     * @param motionPrescriptionLibrary 运动处方库数据
     * @return 结果
     */
    @Override
    public int insertMotionPrescriptionLibrary(MotionPrescriptionLibrary motionPrescriptionLibrary) {
        motionPrescriptionLibrary.setCreateTime(DateUtils.getNowDate());
        return motionPrescriptionLibraryMapper.insertMotionPrescriptionLibrary(motionPrescriptionLibrary);
    }

    /**
     * 修改运动处方库数据
     *
     * @param motionPrescriptionLibrary 运动处方库数据
     * @return 结果
     */
    @Override
    public int updateMotionPrescriptionLibrary(MotionPrescriptionLibrary motionPrescriptionLibrary) {
        motionPrescriptionLibrary.setUpdateTime(DateUtils.getNowDate());
        return motionPrescriptionLibraryMapper.updateMotionPrescriptionLibrary(motionPrescriptionLibrary);
    }

    /**
     * 批量删除运动处方库数据
     *
     * @param ids 需要删除的运动处方库数据主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult deleteMotionPrescriptionLibraryByIds(Long[] ids) {
        //删除主表信息
        int deleteCount = motionPrescriptionLibraryMapper.deleteMotionPrescriptionLibraryByIds(ids);
        if (deleteCount <= 0) {
            throw new ServiceException("运动处方库信息删除失败，请联系管理员！");
        }
        //查询运动处方干预视频信息
        List<MotionPrescriptionVideo> prescriptionLibraryList = motionPrescriptionLibraryMapper.getMotionPrescriptionLibraryByIds(ids);
        if (CollectionUtils.isEmpty(prescriptionLibraryList)) {
            return AjaxResult.success();
        }
        //删除运动处方视频表信息
        int deleteMotionCount = motionPrescriptionLibraryMapper.deleteMotionPrescriptionLibraryByMotionIds(ids);
        if (deleteMotionCount <= 0) {
            log.info("运动处方视频信息表删除失败！");
            throw new ServiceException("运动处方库信息删除失败，请联系管理员！");
        }
        //删除处方库视频文件
        List<String> prescriptionVideoUrlList = prescriptionLibraryList.stream().filter(item -> StringUtils.isNotBlank(item.getPrescriptionVideoUrl())).map(MotionPrescriptionVideo::getPrescriptionVideoUrl).distinct().collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(prescriptionVideoUrlList)) {
            for (String filePath : prescriptionVideoUrlList) {
                FileUtils.deleteSystemFile(filePath);
            }
        }
        return AjaxResult.success();
    }

    /**
     * 处方上传视频
     *
     * @param prescriptionVideoDTO 输入参数
     * @return 上传结果
     * @throws Exception 错误信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult confirmUploadVideo(MotionPrescriptionVideoDTO prescriptionVideoDTO) throws Exception {
        //根据处方库id查询原有的视频信息
        List<String> existMotionPrescriptionVideoList = motionPrescriptionVideoMapper.getMotionPrescriptionVideoUrlList(prescriptionVideoDTO.getMotionPrescriptionId());
        //取出视频名称与视频地址
        List<MotionPrescriptionVideo> motionPrescriptionVideoUrlList = prescriptionVideoDTO.getPrescriptionVideoUrlList();
        List<String> prescriptionVideoUrlList = motionPrescriptionVideoUrlList.stream().filter(Objects::nonNull).filter(video -> (StringUtils.isNotBlank(video.getPrescriptionVideoUrl()))).map(MotionPrescriptionVideo::getPrescriptionVideoUrl).collect(Collectors.toList());
        //求出要新增的视频信息
        List<String> insertUrlList = new ArrayList<>(CollectionUtils.subtract(prescriptionVideoUrlList, existMotionPrescriptionVideoList));
        //求出要删除的视频信息
        List<String> deleteUrlList = new ArrayList<>(CollectionUtils.subtract(existMotionPrescriptionVideoList, prescriptionVideoUrlList));
        //删除原有处方视频干预信息
        if (CollectionUtils.isNotEmpty(deleteUrlList)) {
            int deleteCount = motionPrescriptionVideoMapper.deleteMotionPrescriptionVideoByUrls(deleteUrlList);
            if (deleteCount <= 0) {
                throw new Exception("运动处方干预视频上传失败！请联系管理员！");
            }
        }
        //新增处方视频干预信息
        if (CollectionUtils.isNotEmpty(insertUrlList)) {
            List<MotionPrescriptionVideo> motionPrescriptionVideoList = Lists.newArrayList();
            for (String prescriptionVideoUrl : insertUrlList) {
                List<String> prescriptionVideoName = motionPrescriptionVideoUrlList.stream().filter(url -> (StringUtils.isNotBlank(url.getPrescriptionVideoUrl()) && url.getPrescriptionVideoUrl().equals(prescriptionVideoUrl))).map(MotionPrescriptionVideo::getPrescriptionVideoName).collect(Collectors.toList());
                if (StringUtils.isBlank(prescriptionVideoUrl)) {
                    continue;
                }
                MotionPrescriptionVideo video = new MotionPrescriptionVideo();
                video.setMotionPrescriptionId(prescriptionVideoDTO.getMotionPrescriptionId());
                video.setPrescriptionVideoName(prescriptionVideoName.get(0));
                video.setPrescriptionVideoUrl(prescriptionVideoUrl);
                video.setCreateBy(SecurityUtils.getUsername());
                video.setCreateTime(DateUtils.getNowDate());
                motionPrescriptionVideoList.add(video);
            }
            if (CollectionUtils.isNotEmpty(motionPrescriptionVideoList)) {
                int count = motionPrescriptionVideoMapper.insertMotionPrescriptionVideoList(motionPrescriptionVideoList);
                if (count <= 0) {
                    throw new Exception("运动处方干预视频上传失败！请联系管理员！");
                }
            }
        }
        //删除视频文件
        if (CollectionUtils.isNotEmpty(deleteUrlList)) {
            for (String filePath : deleteUrlList) {
                FileUtils.deleteSystemFile(filePath);
            }
        }
        return AjaxResult.success();
    }

    /**
     * 处方视频上传
     *
     * @param multipartFile        文件
     * @param motionPrescriptionId 处方id
     * @return 上传结果
     * @throws Exception 异常信息
     */
    @Override
    public AjaxResult uploadMotionPrescriptionVideo(MultipartFile multipartFile, Long motionPrescriptionId) throws Exception {
        String uploadPathUrl = XinYiLuConfig.getProfile() + xinYiLuConfig.getPrescriptionVideoUrl() + "/" + motionPrescriptionId;
        String pictureName = FileUploadUtils.uploadVideoUrl(uploadPathUrl, multipartFile, MimeTypeUtils.VIDEO_EXTENSION);
        if (StringUtils.isBlank(pictureName)) {
            throw new ServiceException("视频上传失败，请联系管理员！");
        }
        AjaxResult ajax = AjaxResult.success("上传成功！");
        ajax.put("prescriptionVideoUrl", pictureName);
        ajax.put("prescriptionVideoName", StringUtils.isBlank(multipartFile.getOriginalFilename()) ? "" : multipartFile.getOriginalFilename());
        return ajax;
    }

    /**
     * 查询运动处方干预视频查看方法
     *
     * @param motionPrescriptionId 运动处方库表id
     * @return 干预视频信息集合
     */
    @Override
    public AjaxResult getPrescriptionVideoList(Long motionPrescriptionId) {
        MotionPrescriptionVideo video = new MotionPrescriptionVideo();
        video.setMotionPrescriptionId(motionPrescriptionId);
        return AjaxResult.success(motionPrescriptionVideoMapper.selectMotionPrescriptionVideoList(video));
    }

    /**
     * 查询运动处方库数据
     *
     * @param id 运动处方库数据主键
     * @return 运动处方库数据
     */
    @Override
    public MotionPrescriptionVideoVO getMotionPrescriptionVideoInfo(Long id) {
        MotionPrescriptionVideo video = new MotionPrescriptionVideo();
        video.setMotionPrescriptionId(id);
        List<MotionPrescriptionVideo> motionPrescriptionVideoList = motionPrescriptionVideoMapper.selectMotionPrescriptionVideoList(video);
        if (CollectionUtils.isEmpty(motionPrescriptionVideoList)) {
            MotionPrescriptionVideoVO videoVO = new MotionPrescriptionVideoVO();
            videoVO.setMotionPrescriptionId(id);
            return videoVO;
        }
        List<String> prescriptionVideoUrlList = motionPrescriptionVideoList.stream().filter(item -> StringUtils.isNotBlank(item.getPrescriptionVideoUrl())).map(MotionPrescriptionVideo::getPrescriptionVideoUrl).distinct().collect(Collectors.toList());
        MotionPrescriptionVideoVO videoVO = new MotionPrescriptionVideoVO();
        List<MotionPrescriptionVideo> motionPresent = new ArrayList<>();
        for (String prescriptionVideoUrl : prescriptionVideoUrlList) {
            List<String> prescriptionVideoName = motionPrescriptionVideoList.stream().filter(url -> (StringUtils.isNotBlank(url.getPrescriptionVideoUrl()) && url.getPrescriptionVideoUrl().equals(prescriptionVideoUrl))).map(MotionPrescriptionVideo::getPrescriptionVideoName).collect(Collectors.toList());
            MotionPrescriptionVideo material = new MotionPrescriptionVideo();
            material.setMotionPrescriptionId(id);
            material.setPrescriptionVideoName(prescriptionVideoName.get(0));
            material.setPrescriptionVideoUrl(prescriptionVideoUrl);
            motionPresent.add(material);
        }
        videoVO.setPrescriptionVideoUrlList(motionPresent);
        return videoVO;
    }
}
