package com.fzm.mall.server.admin.goods_center.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.mall.server.admin.constant.MallResponseError;
import com.fzm.mall.server.admin.exception.MyException;
import com.fzm.mall.server.admin.goods_center.entity.dto.CategoryDTO;
import com.fzm.mall.server.admin.goods_center.entity.dto.CategorySaveDTO;
import com.fzm.mall.server.admin.goods_center.entity.dto.CategoryUpdateDTO;
import com.fzm.mall.server.admin.goods_center.enums.status.CommonStatusEnum;
import com.fzm.mall.server.admin.goods_center.mapper.CategoryMapper;
import com.fzm.mall.server.admin.goods_center.mapper.CategorySpuMapper;
import com.fzm.mall.server.admin.goods_center.model.Category;
import com.fzm.mall.server.admin.goods_center.service.ICategoryService;
import com.fzm.mall.server.admin.util.CopyUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

import static com.fzm.mall.server.admin.goods_center.model.Category.CATEGORY_STATUS_EFFECTIVE;

/**
 * <p>
 * 商品类别 服务实现类
 * </p>
 *
 * @author fzm
 * @since 2021-03-04
 */
@Service
@Transactional
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {

    private final CategoryMapper categoryMapper;
    private final CategorySpuMapper categorySpuMapper;

    @Override
    public void save(CategorySaveDTO categorySaveDTO) {
        Category category = CopyUtil.to(categorySaveDTO, Category.class);
        category.init();

        categoryMapper.insert(category);
    }

    @Override
    public void update(CategoryUpdateDTO categoryUpdateDTO) {
        Category category = CopyUtil.to(categoryUpdateDTO, Category.class);
        UpdateWrapper<Category> wrapper = new UpdateWrapper<>();
        wrapper.eq("category_id", category.getCategoryId())
                .eq("update_time", category.getUpdateTime());
        int update = categoryMapper.update(category, wrapper);
        if (update == 0) {
            throw new MyException(MallResponseError.UPDATE_FAIL);
        }
    }

    @Override
    public void delete(String categoryId) {
        /**
         * 根目录不能被删除
         */
        if (categoryId.equals(Category.ROOT_CATEGORY_ID)) {
            return;
        }
        checkBeforeDelete(categoryId);
        /**
         * 添加逻辑删除标识
         */
        Category category = new Category();
        category.setCategoryId(categoryId);
        category.setStatus(Category.CATEGORY_STATUS_DELETED);

        UpdateWrapper<Category> wrapper = new UpdateWrapper<>();
        wrapper.eq("category_id", category.getCategoryId());
        categoryMapper.update(category, wrapper);
    }

    /**
     * 类目删除前校验：
     */
    private void checkBeforeDelete(String categoryId) {
        checkHaveChildren(categoryId);
        chekeBindedGoods(categoryId);
    }

    /**
     * 1.有子类目时不可删除
     */
    private void checkHaveChildren(String categoryId) {
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("clazz_id", categoryId).eq("status", CATEGORY_STATUS_EFFECTIVE);

        List<Category> categoryList = categoryMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(categoryList)) {
            throw new MyException(MallResponseError.DELETE_FAIL);
        }
    }

    /**
     * 2.有已上架商品绑定不可删除
     */
    private void chekeBindedGoods(String categoryId) {
        int count = categorySpuMapper.selectGoodsOnShelves(categoryId);
        if (count > 0) {
            throw new MyException(MallResponseError.DELETE_FAIL);
        }
    }

    @Override
    public List<CategoryDTO> treeList() {
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", CATEGORY_STATUS_EFFECTIVE);
        List<Category> list = categoryMapper.selectList(queryWrapper);

        List<CategoryDTO> originList = CopyUtil.toList(list, CategoryDTO.class);
        List<CategoryDTO> resultList = new ArrayList<>();

        /**
         * 先找到所有一级菜单
         */
        originList.forEach(item -> {
            if (item.getLevel().equals(Category.ROOT_LEVEL) && StringUtils.isBlank(item.getClazzId())) {
                resultList.add(item);
            }
        });

        /**
         * 查找一级菜单的子菜单
         */
        resultList.forEach(item -> {
            item.setChildList(getChild(item.getCategoryId(), originList));
        });
        return resultList;
    }

    @Override
    public Category getById(String categoryId) {
        Integer status = CommonStatusEnum.EFFECTIVE.getStatus();

        QueryWrapper<Category> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(Category::getCategoryId, categoryId)
                .eq(Category::getStatus, status);
        return getOne(qw);
    }

    @Override
    public List<Category> listByCoupon(String couponId, String merchantId) {
        return categoryMapper.listByCoupon(couponId, merchantId);
    }

    @Override
    public List<Category> listByPromotion(String promotionId, String merchantId) {
        return categoryMapper.listByPromotion(promotionId, merchantId);
    }

    private List<CategoryDTO> getChild(String categoryId, List<CategoryDTO> originList) {
        List<CategoryDTO> childList = new ArrayList<>();
        /**
         * 获取当前菜单的子菜单
         */
        originList.forEach(item -> {
            if (categoryId.equals(item.getClazzId())) {
                childList.add(item);
            }
        });

        childList.forEach(item -> {
            item.setChildList(getChild(item.getCategoryId(), originList));
        });

        /**
         * 退出递归
         */
        if (CollectionUtils.isEmpty(childList)) {
            return new ArrayList<>();
        }

        return childList;
    }

    @Override
    public List<Category> listByReturn(String returnId) {
        return categoryMapper.listByReturn(returnId);
    }
}
