package com.securitycontrol.system.service;

import com.securitycontrol.common.core.domain.Result;
import com.securitycontrol.common.core.utils.aes.ListHelper;
import com.securitycontrol.common.core.utils.aes.StringHelper;
import com.securitycontrol.entity.system.dto.DictDto;
import com.securitycontrol.entity.system.vo.DictVo;
import com.securitycontrol.system.mapper.DictMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 字典管理业务层
 *
 * @author HeiZi
 */
@Service
@Slf4j
public class DictServiceImpl implements DictService {

    @Resource
    private DictMapper mapper;

    public final static int P_CODE = 0;

    public final static int MIN_NUM = 0;

    /**
     * 查询字典集合
     *
     * @param dto
     * @return
     */
    @Override
    public Result<List<DictVo>> getDictList(DictDto dto) {
        try {
            List<DictVo> list = mapper.getDictList(dto);
            if (ListHelper.isEmpty(list)) {
                return Result.ok(new ArrayList<>());
            }
            if (StringHelper.isNotEmpty(dto.getKeyWord())) {
                List<DictVo> allList = new ArrayList<>(list);
                List<DictVo> list2 = mapper.getDictList(null);
                for (DictVo dictVo : list) {
                    if (P_CODE != dictVo.getPidCode()) {
                        getParentDict(dictVo.getPidCode(), list2, allList);
                    }
                }
                allList = allList.stream().filter(ListHelper.distinctByKey(DictVo::getDictId)).collect(Collectors.toList());
                return Result.ok(getChildList(allList));
            }
            return Result.ok(getChildList(list));
        } catch (Exception e) {
            log.error(e.toString(), e);
            return Result.ok(new ArrayList<>(), e.toString());
        }
    }

    @Override
    public Result<String> addDict(DictVo dto) {
        try {
            if (dto.getPidCode() == null) {
                dto.setPidCode(0);
            }
            Result<String> res = dataVerify(dto);
            if (res != null) {
                return res;
            }
            int num = mapper.addDict(dto);
            if (num > 0) {
                return Result.ok("新增成功");
            }
            return Result.fail("新增失败");
        } catch (Exception e) {
            log.error(e.toString(), e);
            return Result.fail("服务异常", e.toString());
        }
    }

    @Override
    public Result<String> updateDict(DictVo dto) {
        try {
            //查询数据
            DictVo vo = mapper.getDetails(dto.getDictId().toString());
            if (vo == null) {
                return Result.fail("数据不存在");
            }
            if (vo.getDictCode().equals(dto.getPidCode())) {
                return Result.fail("父节点不能是自己");
            }
            if (dto.getPidCode() == null) {
                dto.setPidCode(0);
            }
            Result<String> res = dataVerify(dto);
            if (res != null) {
                return res;
            }
            int num = mapper.updateDict(dto);
            vo.setPidCode(dto.getDictCode());
            mapper.updateChildCode(vo);
            if (num > 0) {
                return Result.ok("修改成功");
            }
            return Result.fail("修改失败");

        } catch (Exception e) {
            log.error(e.toString(), e);
            return Result.fail("服务异常", e.toString());
        }

    }

    @Override
    public Result<String> delDict(DictDto dto) {
        try {
            int childNum = mapper.getChildNum(dto);
            if (childNum > MIN_NUM) {
                return Result.fail("请先删除子节点数据");
            }
            int num = mapper.delDict(dto);
            if (num > 0) {
                return Result.ok("删除成功");
            }
            return Result.fail("删除失败");

        } catch (Exception e) {
            log.error(e.toString(), e);
            return Result.fail("服务异常", e.toString());

        }
    }

    @Override
    public Result<DictVo> getDetails(String id) {
        try {
            if (StringHelper.isEmpty(id)) {
                return Result.fail("主键不存在");
            }
            DictVo vo = mapper.getDetails(id);
            return Result.ok(vo);
        } catch (Exception e) {
            log.error(e.toString(), e);
            return Result.fail(new DictVo(), e.toString());
        }
    }

    public Result<String> dataVerify(DictVo dictVo) {
        DictVo dto = new DictVo();
        dto.setPidCode(dictVo.getPidCode());
        dto.setDictId(dictVo.getDictId());
        dto.setDictCode(dictVo.getDictCode());
        int codeNum = mapper.getNumByCode(dto);
        if (codeNum > MIN_NUM) {
            return Result.fail("字典编码已存在");
        }
        if (P_CODE == dictVo.getDictCode()) {
            return Result.fail("字典编码不能为0");
        }
        dto.setDictCode(null);
        dto.setDictName(dictVo.getDictName());
        dto.setPidCode(dictVo.getPidCode());
        int nameNum = mapper.getNumByCode(dto);
        if (nameNum > MIN_NUM) {
            return Result.fail("字典名称已存在");
        }
        return null;
    }

    /**
     * 依据下级节点查询上级节点
     *
     * @param pidCode
     * @param list
     * @param list2
     */
    public void getParentDict(int pidCode, List<DictVo> list, List<DictVo> list2) {
        DictVo vo = list.stream().filter(dictVo -> pidCode == dictVo.getDictCode()).findFirst().orElse(null);
        assert vo != null;
        list2.add(vo);
        if (P_CODE != vo.getPidCode()) {
            getParentDict(vo.getPidCode(), list, list2);
        }
    }

    /**
     * 遍历获取
     *
     * @param list
     * @return
     */
    public List<DictVo> getChildList(List<DictVo> list) {
        //map
        list.stream().map(orgVo -> {
            orgVo.setChildren(this.fromTree(orgVo, list));
            return orgVo;
        }).collect(Collectors.toList());
        //过滤出最上级的菜单
        return list.stream()
                .filter(ele -> P_CODE == ele.getPidCode())
                .collect(Collectors.toList());
    }

    /**
     * 找寻指定菜单的下级菜单
     *
     * @param dictVo 当前菜单
     * @param list   所有的菜单list
     * @return 下级菜单
     */
    private List<DictVo> fromTree(DictVo dictVo, List<DictVo> list) {
        return list.stream()
                .filter(ele -> dictVo.getDictCode().toString().equals(ele.getPidCode().toString()))
                .collect(Collectors.toList());
    }
}
