package com.xinelu.manage.service.goodsCategory.impl;

import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.enums.CachePrefix;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.codes.GenerateSystemCodeUtil;
import com.xinelu.manage.domain.goodsCategory.GoodsCategory;
import com.xinelu.manage.mapper.goodsCategory.GoodsCategoryMapper;
import com.xinelu.manage.service.goodsCategory.IGoodsCategoryService;
import com.xinelu.manage.service.nursestationitem.INurseStationItemService;
import com.xinelu.manage.service.patientinfo.IPatientInfoService;
import com.xinelu.manage.vo.goodsCategory.GoodsCategoryVO;
import com.xinelu.manage.vo.goodsCategory.ParentCategory;
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 javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.sun.corba.se.impl.util.RepositoryId.cache;

/**
 * 商品分类信息Service业务层处理
 *
 * @author xinyilu
 * @date 2022-10-17
 */
@Service
public class GoodsCategoryServiceImpl implements IGoodsCategoryService {
    @Resource
    private GoodsCategoryMapper goodsCategoryMapper;
    @Resource
    private GenerateSystemCodeUtil generateSystemCodeUtil;
    @Resource
    private INurseStationItemService nurseStationItemService;
    @Resource
    private IPatientInfoService patientInfoService;

    /**
     * 商品分类的跟级别
     */
    private static final String GOODS_CATEGORY_PARENT_ID = "0";

    /**
     * 商品分类的一级分类的父级id默认值
     */
    private static final Long GOODS_CATEGORY_PARENT_IDS = 0L;

    /**
     * 商品分类的一级分类的级别默认值
     */
    private static final Integer GOODS_CATEGORY_ROOT_LEVEL = 1;

    /**
     * 查询商品分类信息
     *
     * @param id 商品分类信息主键
     * @return 商品分类信息
     */
    @Override
    public ParentCategory selectGoodsCategoryById(Long id) {
        return goodsCategoryMapper.selectParentIdById(id);
    }

    /**
     * 查询商品分类信息列表
     *
     * @param goodsCategory 商品分类信息
     * @return 商品分类信息
     */
    @Override
    public List<GoodsCategory> selectGoodsCategoryList(GoodsCategory goodsCategory) {
        return goodsCategoryMapper.selectGoodsCategoryList(goodsCategory);
    }

    /**
     * 新增商品分类信息
     *
     * @param goodsCategory 商品分类信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertGoodsCategory(GoodsCategory goodsCategory) {
        //根据商品分类名称查询名称数量
        int count = goodsCategoryMapper.getGoodsCategoryNameCount(null, goodsCategory.getGoodsCategoryName());
        if (count > 0) {
            return AjaxResult.error("商品分类名称重复，请重新录入！");
        }

        //若商品分类为一级分类则商品分类图片不能为空
        boolean parentIdEmpty = Objects.isNull(goodsCategory.getParentId()) || goodsCategory.getParentId() == 0;
        boolean pictureEmpty = StringUtils.isEmpty(goodsCategory.getGoodsCategoryPicture());
        if (BooleanUtils.isTrue(parentIdEmpty) && BooleanUtils.isTrue(pictureEmpty)) {
            return AjaxResult.error("商品主分类图片不能为空！");
        }
        //若新增父级id为null，则新增一级分类，否则增父级的下级分类
        if (Objects.isNull(goodsCategory.getParentId()) || goodsCategory.getParentId() == 0) {
            goodsCategory.setCategoryLevel(GOODS_CATEGORY_ROOT_LEVEL);
            goodsCategory.setParentId(GOODS_CATEGORY_PARENT_IDS);
        } else {
            //查询父级分类信息
            GoodsCategory selectGoodsCategory = goodsCategoryMapper.selectGoodsCategoryById(goodsCategory.getParentId());
            if (Objects.isNull(selectGoodsCategory) || Objects.isNull(selectGoodsCategory.getCategoryLevel())) {
                throw new ServiceException("当前分类所属的父级分类信息不存在，请联系管理员！");
            }
            goodsCategory.setCategoryLevel(selectGoodsCategory.getCategoryLevel() + 1);
        }
        //设置创建人创建时间以及生成唯一的商品分类编码
        goodsCategory.setCreateBy(SecurityUtils.getUsername());
        goodsCategory.setCreateTime(LocalDateTime.now());
        goodsCategory.setGoodsCategoryCode(Constants.GOODS_CATEGORY_CODE + generateSystemCodeUtil.generateSystemCode(Constants.GOODS_CATEGORY_CODE));
        int insert = goodsCategoryMapper.insertGoodsCategory(goodsCategory);
        if (insert <= 0) {
            throw new ServiceException("新增商品分类信息失败，请联系管理员！");
        }
        return AjaxResult.success();
    }

    /**
     * 修改商品分类信息
     *
     * @param goodsCategory 商品分类信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateGoodsCategory(GoodsCategory goodsCategory) {
        GoodsCategory goodsCategoryUrl = goodsCategoryMapper.selectGoodsCategoryById(goodsCategory.getId());
        if (Objects.isNull(goodsCategoryUrl)) {
            return AjaxResult.error("当前商品分类信息不存在，请联系管理员！");
        }
        if (Objects.nonNull(goodsCategory.getParentId()) && goodsCategory.getParentId().equals(goodsCategory.getId())) {
            return AjaxResult.error("父级分类名称不能选择当前商品分类名称，请重新选择！");
        }
        //根据商品分类名称查询名称数量
        if (!goodsCategory.getGoodsCategoryName().equals(goodsCategoryUrl.getGoodsCategoryName())) {
            int count = goodsCategoryMapper.getGoodsCategoryNameCount(goodsCategory.getId(), goodsCategory.getGoodsCategoryName());
            if (count > 0) {
                return AjaxResult.error("商品分类名称重复，请重新录入！");
            }
        }
        //若父级id为null，则新增一级分类，否则增父级的下级分类
        if (Objects.isNull(goodsCategory.getParentId()) || goodsCategory.getParentId() == 0) {
            goodsCategory.setCategoryLevel(GOODS_CATEGORY_ROOT_LEVEL);
            goodsCategory.setParentId(GOODS_CATEGORY_PARENT_IDS);
        } else {
            GoodsCategory selectGoodsCategory = goodsCategoryMapper.selectGoodsCategoryById(goodsCategory.getParentId());
            if (Objects.isNull(selectGoodsCategory) || Objects.isNull(selectGoodsCategory.getCategoryLevel())) {
                throw new ServiceException("当前分类所属的父级分类信息不存在，请联系管理员！");
            }
            goodsCategory.setCategoryLevel(selectGoodsCategory.getCategoryLevel() + 1);
        }
        //设置修改人以及修改时间
        goodsCategory.setUpdateBy(SecurityUtils.getUsername());
        goodsCategory.setUpdateTime(LocalDateTime.now());
        int update = goodsCategoryMapper.updateGoodsCategory(goodsCategory);
        if (update <= 0) {
            throw new ServiceException("修改商品分类信息失败，请联系管理员！");
        }
        //删除原有上传的分类图片
        if (StringUtils.isNotBlank(goodsCategoryUrl.getGoodsCategoryPicture()) && StringUtils.isNotBlank(goodsCategory.getGoodsCategoryPicture())
                && !goodsCategory.getGoodsCategoryPicture().equals(goodsCategoryUrl.getGoodsCategoryPicture())) {
            nurseStationItemService.deletePictureUrl(goodsCategoryUrl.getGoodsCategoryPicture());
        }
        return AjaxResult.success();
    }

    /**
     * 批量删除商品分类信息
     *
     * @param ids 需要删除的商品分类信息主键
     * @return 结果
     */
    @Override
    public AjaxResult deleteGoodsCategoryByIds(Long[] ids) {
        //根据id查询本级及下级信息
        List<GoodsCategory> goodsCategories = goodsCategoryMapper.selectCategoryByIds(ids);
        if (ids.length != goodsCategories.size()) {
            return AjaxResult.error("删除失败！该分类存在下级分类！");
        }
        //循环查询本级图片
        List<String> formerPicture = goodsCategories.stream().filter(Objects::nonNull).filter(item -> StringUtils.isNotBlank(item.getGoodsCategoryPicture())).map(GoodsCategory::getGoodsCategoryPicture).distinct().collect(Collectors.toList());
        //删除商品分类信息
        int count = goodsCategoryMapper.deleteGoodsCategoryByIds(ids);
        if (count <= 0) {
            throw new ServiceException("删除商品分类信息失败，请联系管理员！");
        }
        //删除商品主表的图片地址
        if (CollectionUtils.isNotEmpty(formerPicture)) {
            patientInfoService.updatePicture(formerPicture);
        }
        return AjaxResult.success();
    }

    /**
     * 删除商品分类信息信息
     *
     * @param id 商品分类信息主键
     * @return 结果
     */
    @Override
    public int deleteGoodsCategoryById(Long id) {
        return goodsCategoryMapper.deleteGoodsCategoryById(id);
    }


    /**
     * 根据父id查询分类
     *
     * @param parentId 父id
     * @return java.util.List<com.xinyilu.base.vo.goodsCategory.GoodsCategoryVO>
     **/
    @Override
    public List<GoodsCategoryVO> listAllChildren(String parentId) {
        if (GOODS_CATEGORY_PARENT_ID.equals(parentId)) {
            return categoryTree();
        }
        //循环代码，找到对象，把他的子分类返回
        List<GoodsCategoryVO> topCatList = categoryTree();
        for (GoodsCategoryVO item : topCatList) {
            if (item.getId().toString().equals(parentId)) {
                return item.getChildren();
            } else {
                return getChildren(parentId, item.getChildren());
            }
        }
        return new ArrayList<>();
    }


    /**
     * 找出子分类返回
     *
     * @return java.util.List<com.xinyilu.base.vo.goodsCategory.GoodsCategoryVO>
     **/
    @Override
    public List<GoodsCategoryVO> categoryTree() {
        List<GoodsCategoryVO> categoryVOList = (List<GoodsCategoryVO>) cache.get(CachePrefix.CATEGORY);
        if (categoryVOList != null) {
            return categoryVOList;
        }
        //获取全部分类
        GoodsCategory goodsCategory = new GoodsCategory();
        List<GoodsCategory> list = goodsCategoryMapper.selectGoodsCategoryList(goodsCategory);
        //构造分类树
        categoryVOList = new ArrayList<>();
        for (GoodsCategory category : list) {
            if (GOODS_CATEGORY_PARENT_IDS.equals(category.getParentId())) {
                GoodsCategoryVO categoryVO = new GoodsCategoryVO(category);
                categoryVO.setChildren(findChildren(list, categoryVO));
                categoryVOList.add(categoryVO);
            }
        }
        categoryVOList.sort(Comparator.comparing(GoodsCategory::getSort));
        if (!categoryVOList.isEmpty()) {
            cache.put(CachePrefix.CATEGORY, categoryVOList);
            cache.put(CachePrefix.CATEGORY_ARRAY, list);
        }
        return categoryVOList;
    }


    /**
     * 递归自身，找到id等于parentId的对象，获取他的children 返回
     *
     * @param parentId       父ID
     * @param categoryVOList 分类VO
     * @return 子分类列表VO
     */
    private List<GoodsCategoryVO> getChildren(String parentId, List<GoodsCategoryVO> categoryVOList) {
        for (GoodsCategoryVO item : categoryVOList) {
            if (item.getId().toString().equals(parentId)) {
                return item.getChildren();
            }
            if (item.getChildren() != null && !item.getChildren().isEmpty()) {
                return getChildren(parentId, item.getChildren());
            }
        }
        return categoryVOList;
    }

    /**
     * 递归树形VO
     *
     * @param categories 分类列表
     * @param categoryVO 分类VO
     * @return 分类VO列表
     */
    private List<GoodsCategoryVO> findChildren(List<GoodsCategory> categories, GoodsCategoryVO categoryVO) {
        List<GoodsCategoryVO> children = new ArrayList<>();
        categories.forEach(item -> {
            if (item.getParentId().equals(categoryVO.getId())) {
                GoodsCategoryVO temp = new GoodsCategoryVO(item);
                temp.setChildren(findChildren(categories, temp));
                children.add(temp);
            }
        });
        return children;
    }
}
