package com.xinelu.manage.service.goodsInfo.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.StoreOpenStatusEnum;
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.goodsInfo.GoodsInfo;
import com.xinelu.manage.domain.nursestation.NurseStation;
import com.xinelu.manage.domain.storeInfo.StoreInfo;
import com.xinelu.manage.dto.goodsInfo.GoodsAttributeDTO;
import com.xinelu.manage.dto.goodsInfo.GoodsInfoDTO;
import com.xinelu.manage.mapper.goodsAttribute.GoodsAttributeMapper;
import com.xinelu.manage.mapper.goodsAttributeDetails.GoodsAttributeDetailsMapper;
import com.xinelu.manage.mapper.goodsInfo.GoodsInfoMapper;
import com.xinelu.manage.service.goodsInfo.GoodsOperateInfoService;
import com.xinelu.manage.service.goodsInfo.IGoodsInfoService;
import com.xinelu.manage.vo.goodsInfo.GetGoodDetails;
import com.xinelu.manage.vo.goodsInfo.GoodsInfoVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
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 2022-10-17
 */
@Service
public class GoodsInfoServiceImpl implements IGoodsInfoService {
    @Resource
    private GoodsInfoMapper goodsInfoMapper;
    @Resource
    private GenerateSystemCodeUtil generateSystemCodeUtil;
    @Resource
    private GoodsAttributeMapper goodsAttributeMapper;
    @Resource
    private GoodsAttributeDetailsMapper goodsAttributeDetailsMapper;
    @Resource
    private GoodsOperateInfoService goodsOperateInfoService;

    /**
     * 查询商品基本信息
     *
     * @param id 商品基本信息主键
     * @return 商品基本信息
     */
    @Override
    public GoodsInfo selectGoodsInfoById(Long id) {
        return goodsInfoMapper.selectGoodsInfoById(id);
    }

    /**
     * 查询商品基本信息列表
     *
     * @param goodsInfo 商品基本信息
     * @return 商品基本信息
     */
    @Override
    public List<GoodsInfo> selectGoodsInfoList(GoodsInfo goodsInfo) {
        return goodsInfoMapper.selectGoodsInfoList(goodsInfo);
    }

    /**
     * 新增商品基本信息
     *
     * @param goodsInfo 商品基本信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertGoodsInfo(GoodsInfoDTO goodsInfo) {
        if (Objects.isNull(goodsInfo.getNurseStationId())) {
            return AjaxResult.error("请选择所属的护理站！");
        }
        //检验商品价格负数问题和库存数量负数问题
        AjaxResult ajaxResult = judgeGoodsPriceAndStock(goodsInfo);
        if (Objects.nonNull(ajaxResult)) {
            return ajaxResult;
        }
        NurseStation nurseStationById = goodsInfoMapper.getNurseStationById(goodsInfo.getNurseStationId());
        StoreInfo storeInfo = new StoreInfo();
        //根据护理站的id查询店铺信息
        StoreInfo storeInfos = goodsInfoMapper.getStoreInfoById(goodsInfo.getNurseStationId());
        //如果没有就新增
        if (Objects.isNull(storeInfos)) {
            storeInfo.setNurseStationId(nurseStationById.getId());
            storeInfo.setStoreName(nurseStationById.getNurseStationName());
            storeInfo.setStoreCode(Constants.STORE_KEY + generateSystemCodeUtil.generateSystemCode(Constants.STORE_KEY));
            storeInfo.setStoreAddress(nurseStationById.getAddress());
            storeInfo.setPhone(nurseStationById.getPhone());
            storeInfo.setStoreOperator(nurseStationById.getDutyPerson());
            storeInfo.setStoreLogoUrl(nurseStationById.getStationPictureUrl());
            storeInfo.setOpeningStatus(StoreOpenStatusEnum.OPENED.getInfo());
            storeInfo.setOpeningTime(LocalDateTime.now());
            storeInfo.setOccupationStartTime(LocalDateTime.now());
            storeInfo.setCreateTime(LocalDateTime.now());
            storeInfo.setCreateBy(SecurityUtils.getUsername());
            storeInfo.setSort(Objects.isNull(nurseStationById.getSort()) ? 1 : nurseStationById.getSort());
            goodsInfoMapper.insertStoreInfo(storeInfo);
        }
        if (Objects.nonNull(storeInfos)) {
            goodsInfo.setStoreInfoId(storeInfos.getId());
        } else {
            goodsInfo.setStoreInfoId(storeInfo.getId());
        }
        //新增商品主表信息
        goodsInfo.setWhetherShelf(0);
        goodsInfo.setCreateBy(SecurityUtils.getUsername());
        goodsInfo.setCreateTime(LocalDateTime.now());
        goodsInfo.setGoodsCode(Constants.GOODS_CODE + generateSystemCodeUtil.generateSystemCode(Constants.GOODS_CODE));
        int insertGoodsInfo = goodsInfoMapper.insertGoodsInfo(goodsInfo);
        if (insertGoodsInfo <= 0) {
            throw new ServiceException(goodsInfo.getGoodsName() + "-" + "商品新增失败!");
        }
        //新增商品属性表信息
        if (CollectionUtils.isNotEmpty(goodsInfo.getGoodDetailsLists())) {
            for (GoodsAttributeDTO goodsAttribute : goodsInfo.getGoodDetailsLists()) {
                goodsOperateInfoService.integralExchangeFlagCheck(goodsAttribute);
                goodsAttribute.setGoodsId(goodsInfo.getId());
                goodsAttribute.setAttributeDetailsSort(Objects.isNull(goodsAttribute.getAttributeDetailsSort()) ? 1 : goodsAttribute.getAttributeDetailsSort());
                goodsAttribute.setCreateBy(goodsInfo.getCreateBy());
                goodsAttribute.setCreateTime(LocalDateTime.now());
                goodsAttribute.setAttributeCode(Constants.ATTRIBUTE_CODE + generateSystemCodeUtil.generateSystemCode(Constants.ATTRIBUTE_CODE));
                int goodsAttributes = goodsAttributeMapper.insertGoodsAttributes(goodsAttribute);
                if (goodsAttributes <= 0) {
                    throw new ServiceException("新增商品属性表信息失败！");
                }
                //新增明细表信息
                goodsAttribute.setGoodsAttributeId(goodsAttribute.getGoodsAttributeId());
                goodsAttribute.setAttributeDetailsName(goodsAttribute.getAttributeName());
                int addGoodsAttributeDetails = goodsAttributeDetailsMapper.addGoodsAttributeDetails(goodsAttribute);
                if (addGoodsAttributeDetails <= 0) {
                    throw new ServiceException("新增商品属性明细表信息失败！");
                }
            }
        }
        return AjaxResult.success();
    }

    /**
     * 修改商品基本信息
     *
     * @param goodsInfo 商品基本信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateGoodsInfo(GoodsInfoDTO goodsInfo) {
        //检验商品价格负数问题和库存数量负数问题
        AjaxResult ajaxResult = judgeGoodsPriceAndStock(goodsInfo);
        if (Objects.nonNull(ajaxResult)) {
            return ajaxResult;
        }
        if (CollectionUtils.isEmpty(goodsInfo.getGoodDetailsLists())) {
            return AjaxResult.error("请添加商品属性信息！");
        }
        //查询原有商品信息
        GoodsInfo existGoodsPicture = goodsInfoMapper.selectGoodsInfoById(goodsInfo.getId());
        if (Objects.isNull(existGoodsPicture)) {
            return AjaxResult.error("当前商品信息不存在！");
        }
        //查寻数据库已存在的商品属性信息
        List<GoodsAttributeDTO> goodsByIdList = goodsInfoMapper.getGoodsByIdList(goodsInfo.getId());
        //修改商品主表信息
        goodsInfo.setUpdateBy(SecurityUtils.getUsername());
        goodsInfo.setUpdateTime(LocalDateTime.now());
        int insertGoodsInfo = goodsInfoMapper.updateGoodsInfo(goodsInfo);
        if (insertGoodsInfo <= 0) {
            throw new ServiceException(goodsInfo.getGoodsName() + "-" + "商品修改失败!");
        }
        List<GoodsAttributeDTO> goodDetailsLists = goodsInfo.getGoodDetailsLists();
        //获取前端传过来的商品属性表id集合
        List<Long> attributeIdList = goodDetailsLists.stream().filter(Objects::nonNull).map(GoodsAttributeDTO::getGoodsAttributeId).distinct().collect(Collectors.toList());
        List<Long> attributedDetailIdList = goodDetailsLists.stream().filter(Objects::nonNull).map(GoodsAttributeDTO::getAttributeDetailsId).distinct().collect(Collectors.toList());
        //获取当前数据库中原有的商品属性id集合
        List<Long> attributeIdListExist = goodsByIdList.stream().filter(Objects::nonNull).map(GoodsAttributeDTO::getGoodsAttributeId).distinct().collect(Collectors.toList());
        List<Long> attributedDetailIdListExist = goodsByIdList.stream().filter(Objects::nonNull).map(GoodsAttributeDTO::getGoodAttributeDetailsId).distinct().collect(Collectors.toList());
        //求差值，找出需要删除的商品属性id集合
        List<Long> subtractAttributeIdList = new ArrayList<>(CollectionUtils.subtract(attributeIdListExist, attributeIdList));
        List<Long> subtractAttributeDetailIdList = new ArrayList<>(CollectionUtils.subtract(attributedDetailIdListExist, attributedDetailIdList));
        if (CollectionUtils.isNotEmpty(subtractAttributeIdList)) {
            int insertCount = goodsAttributeMapper.deleteGoodsAttributeByIds(subtractAttributeIdList.toArray(new Long[0]));
            if (insertCount <= 0) {
                throw new ServiceException("删除商品属性表失败!");
            }
        }
        if (CollectionUtils.isNotEmpty(subtractAttributeDetailIdList)) {
            int insertCount = goodsAttributeDetailsMapper.deleteGoodsAttributeDetailsByIds(subtractAttributeDetailIdList.toArray(new Long[subtractAttributeIdList.size()]));
            if (insertCount <= 0) {
                throw new ServiceException("删除商品属性明细表失败!");
            }
        }
        //新增和修改商品属性信息
        this.updateGoodsAttributeInfo(goodsInfo, goodDetailsLists, goodsByIdList);
        //删除商品主表图片以及商品富文本图片
        this.deleteGoodPictureUrl(goodsInfo, existGoodsPicture);
        return AjaxResult.success();
    }

    /**
     * 批量删除商品基本信息 未删除图片
     *
     * @param ids 需要删除的商品基本信息主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult deleteGoodsInfoByIds(Long[] ids) {
        //根据商品主表id信息 查询数据
        List<GoodsAttributeDTO> goodsByIdList = goodsInfoMapper.getGoodsByIdLists(Arrays.asList(ids));
        //获取商品主表的图片地址
        List<String> goodsPictureUrlList = goodsByIdList.stream().filter(item -> StringUtils.isNotBlank(item.getGoodsPictureUrl())).map(GoodsAttributeDTO::getGoodsPictureUrl).distinct().collect(Collectors.toList());
        //获取商品属性明细表的图片地址
        List<String> attributePictureUrlLit = goodsByIdList.stream().filter(item -> StringUtils.isNotBlank(item.getAttributePitureUrl())).map(GoodsAttributeDTO::getAttributePitureUrl).distinct().collect(Collectors.toList());
        //获取商品概述
        List<String> goodsRemarkList = goodsByIdList.stream().filter(item -> StringUtils.isNotBlank(item.getGoodsRemark())).map(GoodsAttributeDTO::getGoodsRemark).distinct().collect(Collectors.toList());
        //删除商品主表信息
        int goodsInfoByIds = goodsInfoMapper.deleteGoodsInfoByIds(ids);
        if (goodsInfoByIds <= 0) {
            throw new ServiceException("删除商品主表失败！");
        }
        //获取商品属性表的id
        List<Long> attributeIdListExist = goodsByIdList.stream().filter(item -> Objects.nonNull(item.getGoodsAttributeId())).map(GoodsAttributeDTO::getGoodsAttributeId).distinct().collect(Collectors.toList());
        //获取商品属性明细表的id
        List<Long> attributedDetailIdListExist = goodsByIdList.stream().filter(item -> Objects.nonNull(item.getGoodAttributeDetailsId())).map(GoodsAttributeDTO::getGoodAttributeDetailsId).distinct().collect(Collectors.toList());
        //删除
        if (CollectionUtils.isNotEmpty(attributeIdListExist)) {
            int i = goodsAttributeMapper.deleteGoodsAttributeByIds(attributeIdListExist.toArray(new Long[0]));
            if (i <= 0) {
                throw new ServiceException("删除商品属性表失败!");
            }
        }
        if (CollectionUtils.isNotEmpty(attributedDetailIdListExist)) {
            int i = goodsAttributeDetailsMapper.deleteGoodsAttributeDetailsByIds(attributedDetailIdListExist.toArray(new Long[0]));
            if (i <= 0) {
                throw new ServiceException("删除商品属性明细表失败!");
            }
        }
        //删除商品图片
        goodsPictureUrlList.forEach(this::deletePictureUrl);
        //删除商品属性图片
        attributePictureUrlLit.forEach(this::deletePictureUrl);
        //遍历删除护理站富文本图片地址
        for (String goodsRemark : goodsRemarkList) {
            List<String> goodsRemarkImgSrc = FileUtils.getImgSrc(goodsRemark);
            for (String pictureUrl : goodsRemarkImgSrc) {
                if (StringUtils.isBlank(pictureUrl)) {
                    continue;
                }
                //修改路径
                String substring = pictureUrl.substring(pictureUrl.indexOf("/profile"));
                //删除商品富文本图片
                deletePictureUrl(substring);
            }
        }
        return AjaxResult.success();
    }

    /**
     * 删除商品基本信息信息
     *
     * @param id 商品基本信息主键
     * @return 结果
     */
    @Override
    public int deleteGoodsInfoById(Long id) {
        return goodsInfoMapper.deleteGoodsInfoById(id);
    }

    /**
     * 查询商品基本信息
     *
     * @param goodsInfoVO 商品基本信息
     * @return java.util.List<com.xinyilu.base.vo.goodsInfo.GoodsInfoVO>
     **/
    @Override
    public List<GoodsInfoVO> getGoodsInfoList(GoodsInfoVO goodsInfoVO) {
        return goodsInfoMapper.getGoodsInfoList(goodsInfoVO);
    }

    /**
     * 根据商品id查询商品详细信息
     *
     * @param goodsInfoId 商品详细id
     * @return com.xinyilu.nurseapplet.domain.nursingStationGoods.GoodDetails
     **/
    @Override
    public GetGoodDetails getGoodsDetails(Long goodsInfoId) {
        return goodsInfoMapper.getGoodsDetailsList(goodsInfoId);
    }

    /**
     * 修改商品上架状态基本信息
     *
     * @param goodsInfo 商品基本信息
     * @return 结果
     */
    @Override
    public int updateGoodsWhetherShelf(GoodsInfo goodsInfo) {
        //如果上架状态为1 是上架就有时间
        if (goodsInfo.getWhetherShelf().equals(1)) {
            goodsInfo.setShelfTime(LocalDateTime.now());
        }
        return goodsInfoMapper.updateGoodsWhetherShelf(goodsInfo);
    }

    /**
     * 修改商品属性信息
     *
     * @param goodsInfo        商品信息
     * @param goodDetailsLists 商品属性信息
     * @param goodsByIdList    商品id列表信息
     */
    private void updateGoodsAttributeInfo(GoodsInfoDTO goodsInfo, List<GoodsAttributeDTO> goodDetailsLists, List<GoodsAttributeDTO> goodsByIdList) {
        //新增和修改
        List<String> deletePictureList = Lists.newArrayList();
        for (GoodsAttributeDTO dto : goodDetailsLists) {
            if (Objects.isNull(dto.getGoodsAttributeId())) {
                dto.setGoodsId(goodsInfo.getId());
                dto.setCreateBy(goodsInfo.getCreateBy());
                dto.setCreateTime(LocalDateTime.now());
                dto.setAttributeDetailsSort(Objects.isNull(dto.getAttributeDetailsSort()) ? 1 : dto.getAttributeDetailsSort());
                dto.setAttributeCode(Constants.ATTRIBUTE_CODE + generateSystemCodeUtil.generateSystemCode(Constants.ATTRIBUTE_CODE));
                int goodsAttributese = goodsAttributeMapper.insertGoodsAttributes(dto);
                if (goodsAttributese <= 0) {
                    throw new ServiceException("新增商品属性表信息失败！");
                }
            } else {
                dto.setUpdateBy(goodsInfo.getCreateBy());
                dto.setUpdateTime(LocalDateTime.now());
                dto.setAttributeDetailsSort(Objects.isNull(dto.getAttributeDetailsSort()) ? 1 : dto.getAttributeDetailsSort());
                int updateGoodsAttributes = goodsAttributeMapper.updateGoodsAttributes(dto);
                if (updateGoodsAttributes <= 0) {
                    throw new ServiceException("修改商品属性表信息失败！");
                }
            }
            if (Objects.isNull(dto.getAttributeDetailsId())) {
                goodsOperateInfoService.integralExchangeFlagCheck(dto);
                dto.setGoodsAttributeId(dto.getGoodsAttributeId());
                dto.setAttributeDetailsName(dto.getAttributeName());
                dto.setCreateBy(goodsInfo.getCreateBy());
                dto.setCreateTime(LocalDateTime.now());
                dto.setAttributeDetailsSort(Objects.isNull(dto.getAttributeDetailsSort()) ? 1 : dto.getAttributeDetailsSort());
                int addGoodsAttributeDetails = goodsAttributeDetailsMapper.addGoodsAttributeDetails(dto);
                if (addGoodsAttributeDetails <= 0) {
                    throw new ServiceException("新增商品属性明细表信息失败！");
                }
            } else {
                goodsOperateInfoService.integralExchangeFlagCheck(dto);
                dto.setGoodsAttributeId(dto.getGoodsAttributeId());
                dto.setAttributeDetailsName(dto.getAttributeName());
                dto.setSort(dto.getAttributeDetailsSort());
                dto.setUpdateBy(goodsInfo.getCreateBy());
                dto.setUpdateTime(LocalDateTime.now());
                dto.setAttributeDetailsSort(Objects.isNull(dto.getAttributeDetailsSort()) ? 1 : dto.getAttributeDetailsSort());
                int updateGoodsAttributeDetailss = goodsAttributeDetailsMapper.updateGoodsAttributeDetailss(dto);
                if (updateGoodsAttributeDetailss <= 0) {
                    throw new ServiceException("修改商品属性明细表信息失败！");
                }
                //删除原有图片信息
                GoodsAttributeDTO goodsAttributeDTO = goodsByIdList.stream()
                        .filter(item -> Objects.nonNull(item.getGoodAttributeDetailsId()))
                        .filter(item -> dto.getAttributeDetailsId().equals(item.getGoodAttributeDetailsId()))
                        .findFirst().orElse(new GoodsAttributeDTO());
                if (StringUtils.isNotBlank(goodsAttributeDTO.getAttributePitureUrl())
                        && !goodsAttributeDTO.getAttributePitureUrl().equals(dto.getAttributePitureUrl())) {
                    deletePictureList.add(goodsAttributeDTO.getAttributePitureUrl());
                }
            }
        }
        //批量删除商品属性原有图片
        deletePictureList.forEach(this::deletePictureUrl);
    }

    /**
     * 删除商品主表图片以及商品富文本图片
     *
     * @param goodsInfo         前端传过来的商品信息
     * @param existGoodsPicture 数据库中的商品信息
     **/
    private void deleteGoodPictureUrl(GoodsInfoDTO goodsInfo, GoodsInfo existGoodsPicture) {
        if (StringUtils.isNotBlank(goodsInfo.getGoodsPictureUrl()) && StringUtils.isNotBlank(existGoodsPicture.getGoodsPictureUrl())
                && !goodsInfo.getGoodsPictureUrl().equals(existGoodsPicture.getGoodsPictureUrl())) {
            //删除商品图片主表地址
            this.deletePictureUrl(existGoodsPicture.getGoodsPictureUrl());
        }
        if (StringUtils.isNotBlank(goodsInfo.getGoodsRemark()) && StringUtils.isNotBlank(existGoodsPicture.getGoodsRemark())
                && !goodsInfo.getGoodsRemark().equals(existGoodsPicture.getGoodsRemark())) {
            //数据库中原来有的
            List<String> existGoodsImgSrc = FileUtils.getImgSrc(existGoodsPicture.getGoodsRemark());
            //前端传的
            List<String> goodsImgSrc = FileUtils.getImgSrc(goodsInfo.getGoodsRemark());
            //求图片的差集
            List<String> subtractGoodsImgSrc = new ArrayList<>(CollectionUtils.subtract(existGoodsImgSrc, goodsImgSrc));
            //删除商品图片主表地址GoodsRemark中的图片
            for (String pictureUrl : subtractGoodsImgSrc) {
                if (StringUtils.isBlank(pictureUrl)) {
                    continue;
                }
                //修改路径
                String substring = pictureUrl.substring(pictureUrl.indexOf("/profile"));
                //删除商品富文本图片
                deletePictureUrl(substring);
            }
        }
    }

    /**
     * 删除商品图片地址
     *
     * @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 goodsInfo 输入参数
     * @return 返回结果
     */
    private AjaxResult judgeGoodsPriceAndStock(GoodsInfoDTO goodsInfo) {
        if (CollectionUtils.isNotEmpty(goodsInfo.getGoodDetailsLists())) {
            GoodsAttributeDTO goodsAttributeDTO = goodsInfo.getGoodDetailsLists().stream().filter(item -> Objects.nonNull(item.getGoodsPrice()) && item.getGoodsPrice().compareTo(BigDecimal.ZERO) < 0).findFirst().orElse(null);
            if (Objects.nonNull(goodsAttributeDTO)) {
                return AjaxResult.error("商品单价不能为负数，请重新输入！");
            }
            GoodsAttributeDTO goodStockInfo = goodsInfo.getGoodDetailsLists().stream().filter(item -> Objects.nonNull(item.getGoodsStock()) && item.getGoodsStock() < 0).findFirst().orElse(null);
            if (Objects.nonNull(goodStockInfo)) {
                return AjaxResult.error("商品库存数量不能为负数，请重新输入！");
            }
        }
        return null;
    }
}
