package com.njcn.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.system.enums.EventResponseEnum;
import com.njcn.system.enums.TemplateTreeEnum;
import com.njcn.system.mapper.DicMapper;
import com.njcn.system.pojo.constant.DicState;
import com.njcn.system.pojo.param.DicParam;
import com.njcn.system.pojo.po.Dic;
import com.njcn.system.pojo.po.EventTemplate;
import com.njcn.system.pojo.vo.DicVO;
import com.njcn.system.service.IDicService;
import com.njcn.user.pojo.constant.FunctionState;
import com.njcn.user.pojo.param.FunctionParam;
import com.njcn.user.pojo.po.Function;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author hany
 * @date 2022/10/18
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DicServiceImpl extends ServiceImpl<DicMapper, Dic> implements IDicService {

    private final DicMapper dicMapper;

    @Override
    public boolean addDic(DicParam dicParam) {
        checkDicParam(dicParam,false);
        Dic dic = new Dic();
        BeanUtil.copyProperties(dicParam, dic);
        dic.setStatus(DicState.ENABLE);
        if (Objects.equals(dicParam.getPid(),DicState.FATHER_PID)){
            dic.setPids(DicState.FATHER_PID);
        } else {
            Dic fatherFaction = this.lambdaQuery().eq(Dic::getId,dicParam.getPid()).one();
            if (Objects.equals(fatherFaction.getPid(),DicState.FATHER_PID)){
                dic.setPids(dicParam.getPid());
            } else {
                String pidS = fatherFaction.getPids();
                dic.setPids(pidS+","+dicParam.getPid());
            }
        }
        return this.save(dic);
    }

    @Override
    public boolean updateDic(DicParam.UpdateParam dicParam) {
        checkDicParam(dicParam,true);
        Dic dic = new Dic();
        BeanUtil.copyProperties(dicParam, dic);
        return this.updateById(dic);
    }

    @Override
    public boolean deleteDic(String id) {
        return this.lambdaUpdate().set(Dic::getStatus, DicState.DELETE).in(Dic::getId, id).update();
    }

    @Override
    public Dic getDicById(String id) {
        return this.lambdaQuery().eq(Dic::getId,id).one();
    }

    /**
     * 获取树
     * @return
     */
    @Override
    public List<DicVO> getDicTree() {
        List<DicVO> list = dicMapper.getAllDic();
        return list.stream()
                .filter(fun -> Objects.equals(TemplateTreeEnum.FATHER_PID,fun.getPid()))
                .peek(funS -> funS.setChildren(getChildList(funS, list)))
                .sorted(Comparator.comparingInt(DicVO::getSort))
                .collect(Collectors.toList());
    }

    /**
     * 递归组装
     */
    private List<DicVO> getChildList(DicVO dictMenu, List<DicVO> categories) {
        return categories.stream().filter(o -> Objects.equals(o.getPid(),dictMenu.getId()))
                .peek(o -> o.setChildren(getChildList(o, categories)))
                .sorted(Comparator.comparingInt(DicVO::getSort))
                .collect(Collectors.toList());
    }

    /**
     * 校验参数，
     * 1.检查是否存在相同名称的菜单
     */
    private void checkDicParam(DicParam dicParam, boolean isExcludeSelf) {
        LambdaQueryWrapper<Dic> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper
                .eq(Dic::getName,dicParam.getName())
                .eq(Dic::getStatus, DicState.ENABLE);
        //更新的时候，需排除当前记录
        if (isExcludeSelf) {
            if (dicParam instanceof DicParam.UpdateParam) {
                lambdaQueryWrapper.ne(Dic::getId, ((DicParam.UpdateParam) dicParam).getId());
            }
        }
        int countByAccount = this.count(lambdaQueryWrapper);
        //大于等于1个则表示重复
        if (countByAccount >= 1) {
            throw new BusinessException(EventResponseEnum.NAME_REPEAT);
        }
    }

}
