package com.xinelu.manage.service.poserInfo.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.PoserModuleTypeEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.common.utils.codes.GenerateSystemCodeUtil;
import com.xinelu.common.utils.file.FileUploadUtils;
import com.xinelu.common.utils.file.MimeTypeUtils;
import com.xinelu.manage.dto.poserInfo.PoserInfoDTO;
import com.xinelu.manage.mapper.poserInfo.PoserInfoMapper;
import com.xinelu.manage.service.poserInfo.IPoserInfoService;
import com.xinelu.manage.vo.poserInfo.PoserInfoVO;
import com.xinelu.manage.vo.poserInfo.PosterPictureUrlVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
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.io.File;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 泉医到家系统海报模块信息（包含咨询简介信息）Service业务层处理
 *
 * @author xinyilu
 * @date 2023-02-10
 */
@Service
public class PoserInfoServiceImpl implements IPoserInfoService {
    @Resource
    private PoserInfoMapper poserInfoMapper;
    @Resource
    private GenerateSystemCodeUtil generateSystemCodeUtil;
    @Resource
    private XinELuConfig xinYiLuConfig;

    /**
     * 查询泉医到家系统海报模块信息（包含咨询简介信息）
     *
     * @param id 泉医到家系统海报模块信息（包含咨询简介信息）主键
     * @return 泉医到家系统海报模块信息（包含咨询简介信息）
     */
    @Override
    public PoserInfoVO selectPoserInfoById(Long id) {
        return poserInfoMapper.selectPoserInfoById(id);
    }

    /**
     * 查询泉医到家系统海报模块信息（包含咨询简介信息）列表
     *
     * @param poserInfo 泉医到家系统海报模块信息（包含咨询简介信息）
     * @return 泉医到家系统海报模块信息（包含咨询简介信息）
     */
    @Override
    public List<PoserInfoVO> selectPoserInfoList(PoserInfoVO poserInfo) {
        return poserInfoMapper.selectPoserInfoList(poserInfo);
    }

    /**
     * 新增泉医到家系统海报模块信息（包含咨询简介信息）
     *
     * @param poserInfo 泉医到家系统海报模块信息（包含咨询简介信息）
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertPoserInfo(PoserInfoDTO poserInfo) {
        //校验模块是否为空
        AjaxResult module = this.module(poserInfo);
        if (Objects.nonNull(module)) {
            return module;
        }
        //校验当前模块是否存在
        if (PoserModuleTypeEnum.NURSE_AGENCY_MODULE.getInfo().equals(poserInfo.getModuleType())) {
            int count = poserInfoMapper.getPoserInfoByModuleTypeAndId(poserInfo.getModuleType(), poserInfo.getNurseStationId(), null);
            if (count > 0) {
                String nurseStationName = StringUtils.isBlank(poserInfo.getNurseStationName()) ? "" : poserInfo.getNurseStationName();
                return AjaxResult.error("当前'" + nurseStationName + "'海报模块已经存在，无需再新增，直接在原有模块中进行修改即可！");
            }
        }
        if (PoserModuleTypeEnum.NURSE_ITEM_MODULE.getInfo().equals(poserInfo.getModuleType())) {
            int count = poserInfoMapper.getPoserInfoByModuleTypeAndId(poserInfo.getModuleType(), poserInfo.getNurseStationId(), poserInfo.getNurseItemId());
            if (count > 0) {
                String nurseItemName = StringUtils.isBlank(poserInfo.getNurseItemName()) ? "" : poserInfo.getNurseItemName();
                return AjaxResult.error("当前'" + nurseItemName + "'海报模块已经存在，无需再新增，直接在原有模块中进行修改即可！");
            }
        }
        if (!PoserModuleTypeEnum.NURSE_ITEM_MODULE.getInfo().equals(poserInfo.getModuleType()) && !PoserModuleTypeEnum.NURSE_AGENCY_MODULE.getInfo().equals(poserInfo.getModuleType())) {
            int count = poserInfoMapper.getPoserInfoByModuleTypeAndId(poserInfo.getModuleType(), null, null);
            if (count > 0) {
                String moduleName = getModuleName(StringUtils.isBlank(poserInfo.getModuleType()) ? "" : poserInfo.getModuleType());
                return AjaxResult.error("当前'" + moduleName + "'海报已经存在，无需再新增，直接在原有模块中进行修改即可！");
            }
        }
        List<PoserInfoDTO> poserInfoList = new ArrayList<>();
        //新增信息
        if (CollectionUtils.isNotEmpty(poserInfo.getPosterPictureUrlLists())) {
            for (PosterPictureUrlVO posterPictureUrlList : poserInfo.getPosterPictureUrlLists()) {
                if (StringUtils.isBlank(posterPictureUrlList.getPosterPictureUrl())) {
                    return AjaxResult.error("海报图片不能为空！");
                }
                PoserInfoDTO poserInfoDTO = new PoserInfoDTO();
                BeanUtils.copyProperties(poserInfo, poserInfoDTO);
                poserInfoDTO.setPoserCode(Constants.POSER_CODE + generateSystemCodeUtil.generateSystemCode(Constants.POSER_CODE));
                poserInfoDTO.setPosterPictureUrl(posterPictureUrlList.getPosterPictureUrl());
                poserInfoDTO.setJumpType(StringUtils.isBlank(posterPictureUrlList.getJumpType()) ? "" : posterPictureUrlList.getJumpType());
                poserInfoDTO.setJumpLink(StringUtils.isBlank(posterPictureUrlList.getJumpLink()) ? "" : posterPictureUrlList.getJumpLink());
                poserInfoDTO.setJumpDictId(Objects.isNull(posterPictureUrlList.getJumpDictId()) ? null : posterPictureUrlList.getJumpDictId());
                poserInfoDTO.setCreateBy(SecurityUtils.getUsername());
                poserInfoDTO.setCreateTime(LocalDateTime.now());
                poserInfoList.add(poserInfoDTO);
            }
        }
        int insertPoserInfoList = poserInfoMapper.insertPoserInfoList(poserInfoList);
        if (insertPoserInfoList <= 0) {
            throw new ServiceException("新增信息失败，请联系管理员！");
        }
        return AjaxResult.success();
    }

    /**
     * 修改泉医到家系统海报模块信息（包含咨询简介信息）
     *
     * @param poserInfo 泉医到家系统海报模块信息（包含咨询简介信息）
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updatePoserInfo(PoserInfoDTO poserInfo) {
        //校验模块是否为空
        AjaxResult module = this.module(poserInfo);
        if (Objects.nonNull(module)) {
            return module;
        }
        //根据ModuleType去查询数据已经存在的海报信息
        PoserInfoVO poserInfoDate = new PoserInfoVO();
        poserInfoDate.setModuleType(poserInfo.getModuleType());
        poserInfoDate.setNurseStationId(Objects.isNull(poserInfo.getNurseStationId()) ? null : poserInfo.getNurseStationId());
        poserInfoDate.setNurseItemId(Objects.isNull(poserInfo.getNurseItemId()) ? null : poserInfo.getNurseItemId());
        //查询出数据库中原有的
        List<PoserInfoVO> poserInfoLists = poserInfoMapper.selectPoserInfoByModuleTypeList(poserInfoDate);
        if (CollectionUtils.isEmpty(poserInfoLists)) {
            return AjaxResult.error("当前信息不存在，请联系管理员！");
        }
        //前端传过来的
        List<PosterPictureUrlVO> posterPictureUrlLists = poserInfo.getPosterPictureUrlLists();
        //使用Stream流取出数据库中原有的id
        List<Long> poserInfoLongList = poserInfoLists.stream().filter(Objects::nonNull).filter(pose -> (Objects.nonNull(pose.getId()))).map(PoserInfoVO::getId).distinct().collect(Collectors.toList());
        //使用Stream流取出前端传过来的id
        List<Long> posterPictureUrlLongList = posterPictureUrlLists.stream().filter(Objects::nonNull).filter(pose -> (Objects.nonNull(pose.getId()))).map(PosterPictureUrlVO::getId).distinct().collect(Collectors.toList());
        // 数据库中的与前端原有的做差集
        List<Long> subtractList = new ArrayList<>(CollectionUtils.subtract(poserInfoLongList, posterPictureUrlLongList));
        //判断是否为空 不为空去删
        if (CollectionUtils.isNotEmpty(subtractList)) {
            int deletePoserInfoByIds = poserInfoMapper.deletePoserInfoByIds(subtractList.toArray(new Long[0]));
            if (deletePoserInfoByIds <= 0) {
                throw new ServiceException("删除信息失败，请联系管理员！");
            }
        }
        //循环新增，如果id是空的说明是新增的
        this.insertAndUpdate(posterPictureUrlLists, poserInfo);
        //前端传过来的图片链接
        List<String> ratePosterPictureUrList = posterPictureUrlLists.stream().filter(Objects::nonNull).filter(pose -> (StringUtils.isNotBlank(pose.getPosterPictureUrl()))).map(PosterPictureUrlVO::getPosterPictureUrl).distinct().collect(Collectors.toList());
        //数据库中的图片链接
        List<String> leftPosterPictureUrList = poserInfoLists.stream().filter(Objects::nonNull).filter(pose -> (StringUtils.isNotBlank(pose.getPosterPictureUrl()))).map(PoserInfoVO::getPosterPictureUrl).distinct().collect(Collectors.toList());
        // 图片数据库中的与前端原有的做差集
        List<String> subtractPosterPictureUrList = new ArrayList<>(CollectionUtils.subtract(leftPosterPictureUrList, ratePosterPictureUrList));
        // 删除图片与视频
        this.updateDeletePictureAndVideo(subtractPosterPictureUrList, poserInfoLists, poserInfo);
        return AjaxResult.success();
    }

    /**
     * 批量删除泉医到家系统海报模块信息（包含咨询简介信息）
     *
     * @param ids 需要删除的泉医到家系统海报模块信息（包含咨询简介信息）主键
     * @return 结果
     */
    @Override
    public int deletePoserInfoByIds(Long[] ids) {
        return poserInfoMapper.deletePoserInfoByIds(ids);
    }

    /**
     * 删除泉医到家系统海报模块信息（包含咨询简介信息）信息
     *
     * @param id 泉医到家系统海报模块信息（包含咨询简介信息）主键
     * @return 结果
     */
    @Override
    public int deletePoserInfoById(Long id) {
        return poserInfoMapper.deletePoserInfoById(id);
    }

    /**
     * 根据moduleType 护理站id 与 护理项目id 删除泉医到家系统海报模块信息（包含咨询简介信息）
     *
     * @param poserInfo 需要删除的数据
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult deletePoserInfoByModuleType(PoserInfoVO poserInfo) {
        List<PoserInfoVO> poserInfoLists = poserInfoMapper.selectPoserInfoByModuleTypeList(poserInfo);
        if (CollectionUtils.isEmpty(poserInfoLists)) {
            return AjaxResult.error("当前信息不存在，请联系管理员！");
        }
        //使用Stream流取出id
        Long[] longList = poserInfoLists.stream().filter(Objects::nonNull)
                .filter(pose -> (Objects.nonNull(pose.getId())))
                .map(PoserInfoVO::getId).toArray(Long[]::new);
        int deletePoserInfoByModuleType = poserInfoMapper.deletePoserInfoByIds(longList);
        if (deletePoserInfoByModuleType <= 0) {
            throw new ServiceException("删除失败，请联系管理员！");
        }
        //删除图片与视频地址
        this.deletePictureAndVideo(poserInfoLists);
        return AjaxResult.success();
    }

    /**
     * 头像图片上传接口
     *
     * @param multipartFile 文件
     * @return com.xinyilu.common.core.domain.AjaxResult
     **/
    @Override
    public AjaxResult updatePoserHeads(MultipartFile multipartFile, String type) throws Exception {
        //获取不同的文件路径
        String uploadPathUrl = "";
        //海报视频存放路径地址
        if (Constants.POSTER_VIDEO_URL.equals(type)) {
            uploadPathUrl = XinELuConfig.getProfile() + xinYiLuConfig.getPosterVideoUrl();
        }
        if (StringUtils.isBlank(uploadPathUrl)) {
            return AjaxResult.success();
        }
        //上传
        String pictureName = FileUploadUtils.uploadNurseStationPath(uploadPathUrl, multipartFile, MimeTypeUtils.VIDEO_EXTENSION);
        if (StringUtils.isBlank(pictureName)) {
            throw new ServiceException("视频上传失败，请联系管理员！");
        }
        AjaxResult ajax = AjaxResult.success("上传成功！");
        ajax.put("imgUrl", pictureName);
        return ajax;
    }

    /**
     * 从字典表中查询海报跳转链接
     *
     * @param dictType 类型
     * @return java.util.List<com.xinyilu.common.core.domain.entity.SysDictData>
     **/
    @Override
    public AjaxResult selectPosterImageJump(String dictType) {
        return AjaxResult.success(poserInfoMapper.selectPosterImageJump("poster_image_jump"));
    }

    /**
     * 根据 模块类型 护理站id 护理项目id 查询泉医到家系统海报模块信息（包含咨询简介信息）
     *
     * @param poserInfo 泉医到家系统海报模块信息（包含咨询简介信息）
     * @return 泉医到家系统海报模块信息（包含咨询简介信息）
     */
    @Override
    public AjaxResult selectPoserInfoByModuleType(PoserInfoVO poserInfo) {
        //先根据moduleType查一下数据库
        PoserInfoVO poserInfoVO = new PoserInfoVO();
        List<PoserInfoVO> poserInfoVOList = poserInfoMapper.getPoserInfoList(poserInfo);
        if (poserInfoVOList.size() > 0) {
            BeanUtils.copyProperties(poserInfoVOList.get(0), poserInfoVO);
        }
        //处理海报视频路径
        List<String> posterVideoUrlList = poserInfoVOList.stream().map(PoserInfoVO::getPosterVideoUrl).filter(StringUtils::isNotBlank).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(posterVideoUrlList)) {
            poserInfoVO.setPosterVideoUrl(posterVideoUrlList.get(0));
        }
        List<PosterPictureUrlVO> posterPictureUrlLists = new ArrayList<>();
        poserInfoVOList.forEach(pose -> {
            PosterPictureUrlVO posterPictureUrlList = new PosterPictureUrlVO();
            posterPictureUrlList.setId(pose.getId());
            posterPictureUrlList.setPosterPictureUrl(pose.getPosterPictureUrl());
            posterPictureUrlList.setJumpType(StringUtils.isBlank(pose.getJumpType()) ? "" : pose.getJumpType());
            posterPictureUrlList.setJumpLink(StringUtils.isBlank(pose.getJumpLink()) ? "" : pose.getJumpLink());
            posterPictureUrlList.setJumpDictId(Objects.isNull(pose.getJumpDictId()) ? null : pose.getJumpDictId());
            posterPictureUrlLists.add(posterPictureUrlList);
        });
        poserInfoVO.setPosterPictureUrlLists(posterPictureUrlLists);
        return AjaxResult.success(poserInfoVO);
    }


    /**
     * 校验模块是否为空
     *
     * @param poserInfo 前端传的值
     **/
    private AjaxResult module(PoserInfoDTO poserInfo) {
        //如果选中护理站模块 那么护理站不能为空
        if (PoserModuleTypeEnum.NURSE_AGENCY_MODULE.getInfo().equals(poserInfo.getModuleType())) {
            if (Objects.isNull(poserInfo.getNurseStationId())) {
                return AjaxResult.error("请选择护理站！");
            }
        }
        //如果选中护理项目模块 那么护理项目不能为空
        if (PoserModuleTypeEnum.NURSE_ITEM_MODULE.getInfo().equals(poserInfo.getModuleType())) {
            if (Objects.isNull(poserInfo.getNurseStationId())) {
                return AjaxResult.error("请护理项目所属的护理站！");
            }
            if (Objects.isNull(poserInfo.getNurseItemId())) {
                return AjaxResult.error("请选择护理项目！");
            }
        }
        return null;
    }

    /**
     * 修改提取方法 新增以及修改
     *
     * @param posterPictureUrlLists 前端传过来的取出的图片集合
     * @param poserInfo             前端传过来的数据实体
     **/
    private void insertAndUpdate(List<PosterPictureUrlVO> posterPictureUrlLists, PoserInfoDTO poserInfo) {
        //循环新增 如果id是空的说明是新增的
        if (CollectionUtils.isEmpty(posterPictureUrlLists)) {
            return;
        }
        for (PosterPictureUrlVO posterPictureUrlList : posterPictureUrlLists) {
            if (StringUtils.isBlank(posterPictureUrlList.getPosterPictureUrl())) {
                throw new ServiceException("海报图片不能为空！");
            }
            PoserInfoDTO poserInfoDTO = new PoserInfoDTO();
            if (Objects.isNull(posterPictureUrlList.getId())) {
                BeanUtils.copyProperties(poserInfo, poserInfoDTO);
                poserInfoDTO.setPoserCode(Constants.POSER_CODE + generateSystemCodeUtil.generateSystemCode(Constants.POSER_CODE));
                poserInfoDTO.setPosterPictureUrl(posterPictureUrlList.getPosterPictureUrl());
                poserInfoDTO.setJumpType(StringUtils.isBlank(posterPictureUrlList.getJumpType()) ? "" : posterPictureUrlList.getJumpType());
                poserInfoDTO.setJumpLink(StringUtils.isBlank(posterPictureUrlList.getJumpLink()) ? "" : posterPictureUrlList.getJumpLink());
                poserInfoDTO.setJumpDictId(Objects.isNull(posterPictureUrlList.getJumpDictId()) ? null : posterPictureUrlList.getJumpDictId());
                poserInfoDTO.setCreateBy(SecurityUtils.getUsername());
                poserInfoDTO.setCreateTime(LocalDateTime.now());
                //新增信息
                int insertPoserInfoList = poserInfoMapper.insertPoserInfo(poserInfoDTO);
                if (insertPoserInfoList <= 0) {
                    throw new ServiceException("新增信息失败，请联系管理员！");
                }
            } else {
                //修改方法 塞入固定不变的值与变化的值
                poserInfoDTO.setId(posterPictureUrlList.getId());
                poserInfoDTO.setPosterPictureUrl(posterPictureUrlList.getPosterPictureUrl());
                poserInfoDTO.setJumpType(StringUtils.isBlank(posterPictureUrlList.getJumpType()) ? "" : posterPictureUrlList.getJumpType());
                poserInfoDTO.setPoserCode(posterPictureUrlList.getPoserCode());
                poserInfoDTO.setJumpLink(StringUtils.isBlank(posterPictureUrlList.getJumpLink()) ? "" : posterPictureUrlList.getJumpLink());
                poserInfoDTO.setJumpDictId(Objects.isNull(posterPictureUrlList.getJumpDictId()) ? null : posterPictureUrlList.getJumpDictId());
                poserInfoDTO.setNurseStationId(Objects.isNull(poserInfo.getNurseStationId()) ? null : poserInfo.getNurseStationId());
                poserInfoDTO.setNurseItemId(Objects.isNull(poserInfo.getNurseItemId()) ? null : poserInfo.getNurseItemId());
                poserInfoDTO.setPosterIntroduce(StringUtils.isBlank(poserInfo.getPosterIntroduce()) ? "" : poserInfo.getPosterIntroduce());
                poserInfoDTO.setPosterVideoUrl(StringUtils.isBlank(poserInfo.getPosterVideoUrl()) ? "" : poserInfo.getPosterVideoUrl());
                poserInfoDTO.setPoserName(poserInfo.getPoserName());
                poserInfoDTO.setModuleType(poserInfo.getModuleType());
                poserInfoDTO.setPoserSort(poserInfo.getPoserSort());
                poserInfoDTO.setUpdateBy(SecurityUtils.getUsername());
                poserInfoDTO.setUpdateTime(LocalDateTime.now());
                int updatePoserInfo = poserInfoMapper.updatePoserInfo(poserInfoDTO);
                if (updatePoserInfo < 0) {
                    throw new ServiceException("修改信息失败，请联系管理员！");
                }
            }
        }
    }


    /**
     * 修改方法删除图片地址与视频
     *
     * @param subtractPosterPictureUrList 数据库中的图片  与 前端原有的做差集
     * @param poserInfoLists              查询出数据库中原有的数据
     * @param poserInfo                   前端传过来的数据
     **/
    private void updateDeletePictureAndVideo(List<String> subtractPosterPictureUrList, List<PoserInfoVO> poserInfoLists, PoserInfoDTO poserInfo) {
        //循环删除多个海报图片
        for (String posterPictureUrList : subtractPosterPictureUrList) {
            this.deletePictureUrl(posterPictureUrList);
        }
        //删除海报宣传视频
        if (poserInfoLists.size() > 0 && StringUtils.isNotBlank(poserInfo.getPosterVideoUrl())) {
            //此处视频url路径重复，取第一个即可
            String posterVideoUrl = poserInfoLists.get(0).getPosterVideoUrl();
            if (StringUtils.isNotBlank(posterVideoUrl) && !StringUtils.equals(poserInfo.getPosterVideoUrl(), posterVideoUrl)) {
                this.deletePictureUrl(posterVideoUrl);
            }
        }
    }

    /**
     * 删除图片地址与视频
     *
     * @param poserInfoLists list集合
     **/
    private void deletePictureAndVideo(List<PoserInfoVO> poserInfoLists) {
        //取出视频地址与 图片地址
        List<String> posterPictureUrlList = poserInfoLists.stream().filter(pose -> StringUtils.isNotBlank(pose.getPosterPictureUrl())).map(PoserInfoVO::getPosterPictureUrl).collect(Collectors.toList());
        // 删除图片与视频地址
        for (String posterPictureUrl : posterPictureUrlList) {
            if (StringUtils.isNotBlank(posterPictureUrl)) {
                this.deletePictureUrl(posterPictureUrl);
            }
        }
        //删除视频
        if (poserInfoLists.size() > 0) {
            //此处视频url路径重复，取第一个即可
            String posterVideoUrl = poserInfoLists.get(0).getPosterVideoUrl();
            if (StringUtils.isNotBlank(posterVideoUrl)) {
                this.deletePictureUrl(posterVideoUrl);
            }
        }
    }

    /**
     * 删除图片地址
     *
     * @param pictureUrl 图片地址
     **/
    private void deletePictureUrl(String pictureUrl) {
        if (StringUtils.isBlank(pictureUrl)) {
            return;
        }
        String picture = XinELuConfig.getProfile() + pictureUrl.replaceAll("/profile", "");
        File checkReportNameFile = new File(picture);
        if (checkReportNameFile.exists()) {
            boolean delete = checkReportNameFile.delete();
            if (BooleanUtils.isFalse(delete)) {
                throw new ServiceException("图片地址删除失败！");
            }
        }
    }

    /**
     * 根据模块类型获取模块名称
     *
     * @param moduleType 模块类型
     * @return 模块名称
     */
    private String getModuleName(String moduleType) {
        String moduleName;
        switch (moduleType) {
            case "NURSE_AGENCY_MODULE":
                moduleName = "护理机构模块";
                break;
            case "NURSE_ITEM_MODULE":
                moduleName = "护理项目模块";
                break;
            case "HEALTH_CONSUTION_MODULE":
                moduleName = "健康咨询模块";
                break;
            case "HOME_PAGE_MODULE":
                moduleName = "首页模块";
                break;
            case "NURSE_AGENCY_INTRODUCE_MODULE":
                moduleName = "护理机构简介模块";
                break;
            default:
                moduleName = "";
                break;
        }
        return moduleName;
    }
}
