package com.dxhy.jxpt.baseService.config.service.impl;


import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.dxhy.api.model.config.*;
import com.dxhy.common.constant.RedisConstant;
import com.dxhy.common.util.redis.RedisUtils;
import com.dxhy.jxpt.baseService.config.service.SysUserInfoService;
import com.dxhy.jxpt.baseService.constants.SysConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;


/**
 * @description
 * @author  Allen
 * @date    2023/7/3 16:34
*/
@Service
@Slf4j
public class SysUserInfoServiceImpl implements SysUserInfoService {
    @Resource
    private RedisUtils redisUtils;
    @Override
    public MenuModel getMenuInfo(List<SysMenuEntity> sysMenuList) {
        MenuModel menuModel = new MenuModel();
        List<SysMenuEntity> childPerms = this.getChildPerms(sysMenuList, 0);
        List<RouterVo> routerVos = this.toRouter(childPerms);
        menuModel.setMenus(routerVos);
        Map<String, SysMenuEntity> menuEntityMap = this.toMenuList(childPerms);
        menuModel.setMenuList(menuEntityMap);
        return menuModel;
    }

    @Override
    public Object getDict() {
        return Base64.encode(redisUtils.get(RedisConstant.DICT));
    }

    @Override
    public List<SysMenuEntity> getUserMenuList(List<SysMenuEntity> sysMenuList) {
        return this.getChildPerms(sysMenuList,0);
    }

    /**
     * 菜单信息
     *
     * @param menuEntities
     *            菜单信息
     * @return 菜单信息
     */
    public Map<String, SysMenuEntity> toMenuList(List<SysMenuEntity> menuEntities) {
        Map<String, SysMenuEntity> map = new HashMap<>();
        if (menuEntities.size() > 0) {
            for (SysMenuEntity sysMenuEntity : menuEntities) {
                if (0 == sysMenuEntity.getType()
                        && (sysMenuEntity.getChildren() != null && sysMenuEntity.getChildren().size() > 0)) {
                    List<SysMenuEntity> childrenDirList = sysMenuEntity.getChildren();
                    if (childrenDirList.size() > 0) {
                        for (SysMenuEntity childrenDir : childrenDirList) {
                            List<SysMenuEntity> childrenMenuList = childrenDir.getChildren();

                            if (1 == childrenDir.getType()
                                    && (childrenMenuList != null && childrenMenuList.size() > 0)) {
                                for (SysMenuEntity childrenMenu : childrenMenuList) {
                                    if (2 == childrenMenu.getType()) {
                                        ButtonQueryVo buttonQueryVo = this.toButtonQuery(childrenMenu);
                                        childrenMenu.setMeta(
                                                new MetaVo(childrenMenu.getName(), "", buttonQueryVo.getButtonVos(),
                                                        childrenMenu.isNoCache(), buttonQueryVo.getQueryVos()));
                                        map.put(childrenMenu.getUrl().replaceAll("/", ""), childrenMenu);
                                    }

                                }
                            }
                        }
                    }

                }
            }
        }
        return map;
    }


    /**
     * 转换按钮信息
     *
     * @param sysMenuEntity
     *            菜单信息
     * @return 按钮信息
     */
    public ButtonQueryVo toButtonQuery(SysMenuEntity sysMenuEntity) {
        ButtonQueryVo buttonQueryVo = new ButtonQueryVo();
        List<ButtonVo> buttonVoList = new ArrayList<>();
        List<QueryVo> queryVoList = new ArrayList<>();
        List<SysMenuEntity> children = sysMenuEntity.getChildren();
        if (children != null && children.size() > 0) {
            for (SysMenuEntity menuEntity : children) {
                if (3 == menuEntity.getType()) {
                    buttonVoList.add(new ButtonVo(menuEntity.getMenuCode(), menuEntity.getName(), menuEntity.getUrl()));
                }
                if (4 == menuEntity.getType()) {
                    queryVoList.add(new QueryVo(menuEntity.getMenuCode(), menuEntity.getName()));
                }
            }
        }
        buttonQueryVo.setButtonVos(buttonVoList);
        buttonQueryVo.setQueryVos(queryVoList);
        return buttonQueryVo;

    }

    /**
     * 菜单路由转换
     *
     * @param childPerms
     *            树状菜单信息
     * @return 转换后路由信息
     */
    private List<RouterVo> toRouter(List<SysMenuEntity> childPerms) {
        String path;
        boolean flg = false;
        RouterVo router;
        List<RouterVo> routerVos;

        if (childPerms.size() == 1) {
            childPerms = childPerms.get(0).getChildren();
            routerVos = this.buildMenus(childPerms);
        } else {
            routerVos = this.buildMenusSystem(childPerms);
        }
        if (routerVos != null && routerVos.size() > 0) {
            for (RouterVo routerVo : routerVos) {
                if (routerVo.getMenuType() != SysConfig.TYPE_SYSTEM) {
                    flg = true;
                    break;
                }
            }
            if (flg) {
                RouterVo routerVo = routerVos.get(0);
                List<RouterVo> children = routerVo.getChildren();
                if (children != null && children.size() > 0) {
                    path = children.get(0).getPath();
                    routerVo.setRedirect(path);
                    routerVo.setPath("");
                } else {
                    path = routerVo.getPath();
                    routerVo.setRedirect(path);
                    routerVo.setPath("");
                    router = new RouterVo();
                    List<RouterVo> childrenList = new ArrayList<>();
                    SysMenuEntity sysMenuEntity = childPerms.get(0);
                    router.setComponent(sysMenuEntity.getComponent());
                    router.setPath(sysMenuEntity.getUrl());
                    router.setMeta(new MetaVo(sysMenuEntity.getName(), sysMenuEntity.getIcon(), null,
                            sysMenuEntity.isNoCache(), null));
                    router.setName(StringUtils.capitalize(sysMenuEntity.getUrl().replaceAll("/", "")));
                    router.setMenuId(String.valueOf(sysMenuEntity.getMenuId()));
                    childrenList.add(router);
                    routerVo.setChildren(childrenList);
                    routerVo.setAlwaysShow(false);
                }
            } else {
                router = new RouterVo();
                router.setPath("/");
                RouterVo routerVo = routerVos.get(0);
                List<RouterVo> children = routerVo.getChildren();
                RouterVo routerVoDir = children.get(0);
                List<RouterVo> childrenMenu = routerVoDir.getChildren();
                if (childrenMenu != null && childrenMenu.size() > 0) {
                    log.info("无首页，默认跳转第一个目录第一个菜单");
                    router.setRedirect(childrenMenu.get(0).getPath());
                } else {
                    log.info("有首页，默认跳转首页");
                    router.setRedirect(routerVoDir.getPath());
                }
                routerVos.add(router);
            }
        } else {
            // 没有分配菜单权限返回跳转到欢迎页
            routerVos = new ArrayList<>();
            routerVos.add(this.toRouter());
        }
        return routerVos;
    }

    /**
     * 无菜单信息返回固定首页到欢迎页
     *
     * @return 路由信息
     */
    public RouterVo toRouter() {
        RouterVo routerVoM = new RouterVo();
        List<RouterVo> childrenList = new ArrayList<>();
        routerVoM.setPath("");
        routerVoM.setName("");
        routerVoM.setRedirect("/home");
        routerVoM.setAlwaysShow(false);
        routerVoM.setComponent(SysConfig.LAYOUT);
        routerVoM.setMeta(new MetaVo("首页", "icon_index_good", null, false, null));
        RouterVo router = new RouterVo();
        router.setComponent("home/index");
        router.setMeta(new MetaVo("首页", "icon_index_good", null, false, null));
        router.setName("Home");
        router.setPath("/home");
        router.setMenuId("");
        childrenList.add(router);
        routerVoM.setChildren(childrenList);
        return routerVoM;
    }


    /**
     * 构建前端路由所需要的菜单
     *
     * @param menus
     *            菜单列表
     * @return 路由列表
     */
    public List<RouterVo> buildMenusSystem(List<SysMenuEntity> menus) {
        List<RouterVo> routers = new LinkedList<>();
        for (SysMenuEntity menu : menus) {
            RouterVo router = new RouterVo();
            router.setMenuId(String.valueOf(menu.getMenuId()));
            if (menu.getType() == SysConfig.TYPE_SYSTEM) {
                router.setName("");
            } else {
                router.setName(StringUtils.capitalize(menu.getUrl().replaceAll("/", "")));
            }

            router.setPath(menu.getUrl());

            if (menu.getType() != SysConfig.TYPE_SYSTEM) {
                router.setComponent(menu.getComponent());
            } else {
                router.setComponent(SysConfig.LAYOUT);
            }
            if (menu.getType() == SysConfig.TYPE_MENU) {
                router.setMeta(new MetaVo(menu.getName(), menu.getIcon(), null, menu.isNoCache(), null));
            } else {
                router.setMeta(new MetaVo(menu.getName(), menu.getIcon(), null, menu.isNoCache(), null));
            }
            router.setMenuType(menu.getType());
            router.setSystemCode(menu.getMenuCode());
            List<SysMenuEntity> cMenus = menu.getChildren();
            boolean typeFlg = SysConfig.TYPE_SYSTEM == menu.getType() || SysConfig.TYPE_DIR == menu.getType();
            if (typeFlg && cMenus != null && cMenus.size() > 0) {
                router.setAlwaysShow(true);
                router.setRedirect("noRedirect");
                router.setChildren(buildMenusSystem(cMenus));
            } else if (isMeunFrame(menu)) {
                log.info("不是菜单并且不等于0");
                List<RouterVo> childrenList = new ArrayList<>();
                RouterVo children = new RouterVo();
                children.setPath(menu.getUrl());
                children.setComponent(menu.getComponent());
                children.setName(StringUtils.capitalize(menu.getUrl().replaceAll("/", "")));
                children.setMeta(new MetaVo(menu.getName(), menu.getIcon(), null, menu.isNoCache(), null));
                childrenList.add(children);
                router.setChildren(childrenList);
            }
            routers.add(router);
        }
        return routers;
    }

    /**
     * 构建前端路由所需要的菜单
     *
     * @param menus
     *            菜单列表
     * @return 路由列表
     */
    public List<RouterVo> buildMenus(List<SysMenuEntity> menus) {
        List<RouterVo> routers = new LinkedList<>();
        for (SysMenuEntity menu : menus) {
            RouterVo router = new RouterVo();
            router.setMenuId(String.valueOf(menu.getMenuId()));

            if (menu.getType() == SysConfig.TYPE_MENU) {
                router.setMeta(new MetaVo(menu.getName(), menu.getIcon(), null, menu.isNoCache(), null));
            } else {
                router.setMeta(new MetaVo(menu.getName(), menu.getIcon(), null, menu.isNoCache(), null));

            }
            router.setPath(menu.getUrl());

            if (menu.getType() == SysConfig.TYPE_DIR) {
                router.setName("");
                router.setComponent(SysConfig.LAYOUT);
            } else {
                router.setComponent(menu.getComponent());
                router.setName(StringUtils.capitalize(menu.getUrl().replaceAll("/", "")));
            }
            router.setMenuType(menu.getType());
            router.setSystemCode(menu.getMenuCode());
            List<SysMenuEntity> cMenus = menu.getChildren();
            if (SysConfig.TYPE_DIR == menu.getType() && cMenus != null && cMenus.size() > 0) {
                router.setAlwaysShow(true);
                router.setRedirect(menu.getUrl() + "/index");
                router.setChildren(buildMenus(cMenus));
            } else if (isMeunFrame(menu)) {
                log.info("不是菜单并且不等于0");
                List<RouterVo> childrenList = new ArrayList<>();
                RouterVo children = new RouterVo();
                children.setPath(menu.getUrl());
                children.setComponent(menu.getComponent());
                children.setName(StringUtils.capitalize(menu.getUrl().replaceAll("/", "")));
                children.setMeta(new MetaVo(menu.getName(), menu.getIcon(), null, menu.isNoCache(), null));
                childrenList.add(children);
                router.setChildren(childrenList);
            }
            routers.add(router);
        }
        return routers;
    }

    /**
     * 是否为系统信息
     *
     * @param menu
     *            菜单信息
     * @return 结果
     */
    public boolean isMeunFrame(SysMenuEntity menu) {
        return menu.getParentId().intValue() == 0 && SysConfig.TYPE_MENU == menu.getType();
    }

    /**
     * 根据父节点的ID获取所有子节点
     *
     * @param list
     *            分类表
     * @param parentId
     *            传入的父节点ID
     * @return String
     */
    public List<SysMenuEntity> getChildPerms(List<SysMenuEntity> list, int parentId) {
        List<SysMenuEntity> returnList = new ArrayList<>();
        for (SysMenuEntity t : list) {
            // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (t.getParentId() == parentId) {

                recursionFn(list, t);
                returnList.add(t);
            }
        }
//        log.debug("树状结构：{}", JSON.toJSONString(returnList));
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     *            菜单列
     * @param t
     *            菜单信息
     */
    private void recursionFn(List<SysMenuEntity> list, SysMenuEntity t) {
        // 得到子节点列表
        List<SysMenuEntity> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysMenuEntity tChild : childList) {
            if (hasChild(list, tChild)) {
                // 判断是否有子节点
                for (SysMenuEntity n : childList) {
                    recursionFn(list, n);
                }
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysMenuEntity> getChildList(List<SysMenuEntity> list, SysMenuEntity t) {
        List<SysMenuEntity> tlist = new ArrayList<>();
        for (SysMenuEntity n : list) {
            if (n.getParentId().longValue() == t.getMenuId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysMenuEntity> list, SysMenuEntity t) {
        return getChildList(list, t).size() > 0;
    }
}
