/**
 * 文件：MateriaCategoryServiceImpl.java 版本：1.0.0 日期： Copyright &reg; All right
 * reserved.
 */

package com.mortals.xhx.module.materia.service.impl;

import com.mortals.framework.common.code.YesNo;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.xhx.module.materia.dao.MateriaCategoryDao;
import com.mortals.xhx.module.materia.model.MateriaCategoryEntity;
import com.mortals.xhx.module.materia.model.MateriaCategoryQuery;
import com.mortals.xhx.module.materia.service.MateriaCategoryService;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

/**
 * <p>
 * Title: 产品类目表
 * </p>
 * <p>
 * Description: MateriaCategoryServiceImpl service接口
 * </p>
 * <p>
 * Copyright: Copyright &reg;
 * </p>
 * <p>
 * Company:
 * </p>
 *
 * @author
 * @version 1.0.0
 */
@Service("materiaCategoryService")
public class MateriaCategoryServiceImpl extends AbstractCRUDServiceImpl<MateriaCategoryDao, MateriaCategoryEntity, Long>
        implements MateriaCategoryService {


    @Override
    protected void saveBefore(MateriaCategoryEntity entity, Context context) throws AppException {
        setCode(entity);
        super.saveBefore(entity, context);
    }


    @Override
    protected void saveAfter(MateriaCategoryEntity entity, Context context) throws AppException {
        updateParent(entity);// 更新父节点信息
        super.saveAfter(entity, context);
    }

    /**
     * 设置code
     *
     * @param entity
     */
    private void setCode(MateriaCategoryEntity entity) {
        if(ObjectUtils.isEmpty(entity.getParentId())){
            entity.setParentId(-1L);
        }
        if (entity.getParentId() == -1) {
            //系统自动添加短代码，获取同级目录的最大值
            MateriaCategoryQuery query = new MateriaCategoryQuery();
            query.setParentId(-1L);
            int max = this.find(query, null).stream().mapToInt(item -> Integer.parseInt(item.getSelfCode())).max().orElseGet(() -> 9);
            int cur = max + 1;
            if(cur >=100){
                throw new AppException("当前类目短代码已经超过最大值100，请选择其他目录新建！");
            }
            entity.setCode(String.valueOf(cur));
            entity.setSelfCode(String.valueOf(cur));
        } else {

            MateriaCategoryQuery query = new MateriaCategoryQuery();
            query.setParentId(entity.getParentId());
            int max = this.find(query, null).stream().mapToInt(item -> Integer.parseInt(item.getSelfCode())).max().orElseGet(() -> 9);
            int cur = max + 1;
            if(cur >=100){
                throw new AppException("当前类目短代码已经超过最大值100，请选择其他目录新建！");
            }
            entity.setSelfCode(String.valueOf(cur));

            MateriaCategoryEntity pCategory = this.get(entity.getParentId(), true);
            entity.setCode(pCategory.getCode() + entity.getSelfCode());
        }
    }

    // 更新父节点信息
    private void updateParent(MateriaCategoryEntity entity) {
        if (entity.getParentId() == -1) {
            return;
        }
        MateriaCategoryEntity parent = new MateriaCategoryEntity();
        parent.setId(entity.getParentId());
        parent.setIsLeaf(YesNo.NO.getValue());
        this.getDao().update(parent);
    }

    @Override
    protected void validData(MateriaCategoryEntity entity, Context context) throws AppException {
        if (entity.newEntity()) { // 新增时，同一分类下类目代码不能重复
            MateriaCategoryQuery query = new MateriaCategoryQuery();
            query.setParentId(entity.getParentId());
            query.setCode(entity.getCode());
            if (this.count(query, context) > 0) {
                throw new AppException("同一类目下子类目代码不能重复");
            }

            //检查新增目录是否超过最大级数
            boolean checklevel = checklevel(entity.getParentId(), 1, context);
            if(!checklevel){
                throw new AppException("添加的子目录超过最大目录数！");
            }
        }

        super.validData(entity, context);
    }

    /**
     * @Description 根据parentId查询当前Level
     * @param parentId
     * @param level
     * @param context
     * @Return boolean
     * @date 2021/3/18 16:53
     */
    @Override
    public boolean checklevel(Long parentId, Integer level, Context context) {
        MateriaCategoryEntity materiaCategoryEntity = this.get(parentId, context);

        if(ObjectUtils.isEmpty(materiaCategoryEntity)){
            return true;
        }

        if (materiaCategoryEntity.getParentId() != -1) {
            level++;
            return checklevel(materiaCategoryEntity.getParentId(), level, context);
        } else {
            return level >= 3 ? false : true;
        }
    }

}