package com.yiboshi.science.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yiboshi.science.base.BaseServiceImpl;
import com.yiboshi.science.base.Pagination;
import com.yiboshi.science.config.security.SecurityUserHolder;
import com.yiboshi.science.dao.SystemMenuDAO;
import com.yiboshi.science.entity.SystemMenu;
import com.yiboshi.science.enumeration.CommonEnum;
import com.yiboshi.science.param.dto.MenuTreeDTO;
import com.yiboshi.science.param.dto.Slots;
import com.yiboshi.science.param.dto.SystemMenuDTO;
import com.yiboshi.science.param.dto.UserMenuDTO;
import com.yiboshi.science.param.query.SystemMenuQueryVO;
import com.yiboshi.science.service.SystemMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 菜单表 Service 实现类
 *
 * @author lkl
 * @version 2021-08-26
 */
@Service
public class SystemMenuServiceImpl extends BaseServiceImpl<SystemMenuDAO, SystemMenuQueryVO, SystemMenuDTO, SystemMenu> implements SystemMenuService {
    @Autowired
    private SystemMenuDAO systemMenuDAO;

    @Override
    protected void setCriteriaForQuery(SystemMenuQueryVO vo, QueryWrapper<SystemMenuQueryVO> criteria) {
        if (Objects.nonNull(vo.getMenuId())) {
            criteria.eq("menu_id", vo.getMenuId());
        }
        if (Objects.nonNull(vo.getMenuName())) {
            criteria.like("menu_name", vo.getMenuName());
        }
        if (Objects.nonNull(vo.getActionUrl())) {
            criteria.eq("action_url", vo.getActionUrl());
        }
        if (Objects.nonNull(vo.getWindowPara())) {
            criteria.eq("window_para", vo.getWindowPara());
        }
        if (Objects.nonNull(vo.getShowIndex())) {
            criteria.eq("show_index", vo.getShowIndex());
        }
        if (Objects.nonNull(vo.getParentId())) {
            criteria.eq("parent_id", vo.getParentId());
        }
    }

    @Override
    public Pagination<SystemMenuDTO> getListByPage(SystemMenuQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        Page<SystemMenuQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<SystemMenuDTO> dtoList = systemMenuDAO.getListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    public SystemMenu getSystemMenuById(String id) {
        SystemMenu systemMenu = this.entityById(id);
        if (null == systemMenu.getKeepAlive())
            systemMenu.setKeepAlive(0);
        return systemMenu;
    }

    @Override
    public List<UserMenuDTO> findByRoleId(String roleId) {
        QueryWrapper<SystemMenu> wrapper = new QueryWrapper<SystemMenu>();
        List<String> resultList = new ArrayList<>();
        String[] arr = roleId.split(",");
        for (int i = 0; i < arr.length; i++) {
            resultList.add(arr[i]);
        }
        wrapper.in("b.role_id", resultList);
        List<SystemMenuDTO> list = systemMenuDAO.findByRoleId(wrapper);
        //父级菜单
        List<UserMenuDTO> ParMenuList = new ArrayList<>();
        List<SystemMenuDTO> parentList = new ArrayList<>();
        parentList = list.stream().filter(e -> e.getParentId() == null).collect(Collectors.toList());
        for (SystemMenuDTO parent : parentList) {
            UserMenuDTO Menu = new UserMenuDTO();
            Menu.setId(Integer.parseInt(parent.getId()));
            Menu.setParentId(Integer.parseInt(parent.getId()));
//            Menu.setSystemId(roleId);
            Menu.setName(parent.getMenuName());
            Menu.setIcon(parent.getIcon());
            Menu.setCode(parent.getWindowPara());
            Menu.setDescription(parent.getMenuName());
            Menu.setValid(1);
            Menu.setSortCode(0);
            Menu.setType(1);
            Menu.setValid(0);
            Menu.setKeepAlive(parent.getKeepAlive());
            Menu.setCreateTime(parent.getCreated());
            Menu.setUpdateTime(parent.getUpdated());
            Menu.setFrontActionUrl(parent.getActionUrl());
            Menu.setIsGray(1);
            //子菜单
            List<UserMenuDTO> childMenuList = new ArrayList<>();
            List<SystemMenuDTO> sysChild = new ArrayList<>();
            sysChild = list.stream().filter(x -> x.getParentId() != null && x.getParentId().equals(parent.getId())).collect(Collectors.toList());
            for (SystemMenuDTO child : sysChild) {
                UserMenuDTO childMenu = new UserMenuDTO();
                childMenu.setId(Integer.parseInt(child.getId()));
                childMenu.setParentId(Integer.parseInt(parent.getId()));
//                childMenu.setSystemId(roleId);
                childMenu.setName(child.getMenuName());
                childMenu.setCode(child.getWindowPara());
                childMenu.setIcon(child.getIcon());
                childMenu.setDescription(child.getMenuName());
                childMenu.setValid(1);
                childMenu.setSortCode(0);
                childMenu.setType(1);
                childMenu.setValid(0);
                childMenu.setKeepAlive(child.getKeepAlive());
                childMenu.setCreateTime(child.getCreated());
                childMenu.setUpdateTime(child.getUpdated());
                childMenu.setFrontActionUrl(child.getActionUrl());
                childMenu.setIsGray(1);
                childMenuList.add(childMenu);
            }
            Menu.setChildren(childMenuList);
            ParMenuList.add(Menu);
        }
        return ParMenuList;
    }

    public List<MenuTreeDTO> getAllMenuTree() {
        List<SystemMenu> menuList = this.entityList(new SystemMenu());
        List<SystemMenu> mainMenu = menuList.stream().filter(e -> Objects.isNull(e.getParentId())).collect(Collectors.toList());
        List<SystemMenu> childMenu = menuList.stream().filter(e -> Objects.nonNull(e.getParentId())).collect(Collectors.toList());

        List<MenuTreeDTO> menuTreeList = new ArrayList<>();
        mainMenu.forEach(e -> {
            MenuTreeDTO menuTree = new MenuTreeDTO();
            menuTree.setDisabled(false);
            menuTree.setKey(e.getId());
            menuTree.setTitle(e.getMenuName());
            menuTree.setLeaf(false);
            Slots slots = new Slots();
            slots.setIcon("folder-open");
            menuTree.setSlots(slots);
            menuTree.setChildren(createMenuTreeNode(e.getId(), childMenu));
            menuTreeList.add(menuTree);
        });

        return menuTreeList;
    }

    public List<MenuTreeDTO> createMenuTreeNode(String parentId, List<SystemMenu> childMenu) {
        List<SystemMenu> findMenuList = childMenu.stream().filter(e -> e.getParentId().equals(parentId)).collect(Collectors.toList());
        if (findMenuList.size() <= 0)
            return null;

        List<MenuTreeDTO> menuTreeList = new ArrayList<>();
        findMenuList.forEach(e -> {
            MenuTreeDTO menuTree = new MenuTreeDTO();
            menuTree.setDisabled(false);
            menuTree.setKey(e.getId());
            menuTree.setTitle(e.getMenuName());
            if (null != e.getParentId()) {
                List<MenuTreeDTO> childrenList = createMenuTreeNode(e.getId(), childMenu);
                menuTree.setChildren(childrenList);
                if (null == childrenList)
                    menuTree.setLeaf(true);
                else
                    menuTree.setLeaf(false);
                Slots slots = new Slots();
                slots.setIcon("container");
                menuTree.setSlots(slots);
                menuTreeList.add(menuTree);
            }
        });

        return menuTreeList;
    }

    public List<SystemMenu> getSystemMenuByParentId(String parentId) {
        SystemMenu systemMenu = new SystemMenu();
        systemMenu.setParentId(parentId);
        return this.entityList(systemMenu);
    }

    public String insertSystemMenu(SystemMenu systemMenu) {
        this.save(systemMenu);
        return "菜单信息添加成功！";
    }

    public String updateSystemMenu(SystemMenu systemMenu) {
        this.update(systemMenu);
        return "菜单信息更新成功！";
    }
}