package cc.smtweb.system.bpm.web.sys.user.menuPlan;

import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.framework.core.util.JsonUtil;
import cc.smtweb.system.bpm.web.sys.user.menu.Menu;
import cc.smtweb.system.bpm.web.sys.user.menu.MenuCache;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @Author: tanghp
 * @Date: 2022-08-02 13:16
 * @Desc: 菜单方案content字段处理类
 */
public class MenuPlanContent {
    private List<MenuPlanItem> list = new ArrayList<>();

    public MenuPlanContent(String content) {
        List<MenuPlanItem> tempList = JsonUtil.parseList(content, MenuPlanItem.class);
        if (tempList != null) {
            list = tempList;
        }
        Collections.sort(list, new MenuPlanComparator());
    }

    // 保存节点
    public void saveItem(MenuPlanItem item, long parentId) {
        boolean isNew = item.getId() <= 0;
        if (isNew) {
            item.setId(DbEngine.getInstance().nextId());
            if (parentId <= 0) {
                list.add(item);
            } else {
                MenuPlanItem parentItem = findById(parentId);
                if (parentItem == null) {
                    throw new BizException("上级节点无效");
                }
                List<MenuPlanItem> children = parentItem.getChildren();
                if (children == null) {
                    children = new ArrayList<>();
                    parentItem.setChildren(children);
                }
                children.add(item);
            }
        } else {
            if (item.getId() == parentId) {
                throw new BizException("上级不允许选自己！");
            }
            MenuPlanItem oldItem = findById(item.getId());
            if (oldItem == null) {
                throw new BizException("未找到修改对象");
            }
            // 判断是否修改了父节点
            MenuPlanItem oldParent = findParentById(item.getId());
            MenuPlanItem newParent = findById(parentId);
            boolean changeParent = (oldParent == null ? -1: oldParent.getId()) != parentId;
            if (changeParent) {
                // 改了父节点 父节点的children需要移除，新的父节点需要添加
                removeById(item.getId(), oldParent == null ? list: oldParent.getChildren());
                if (newParent == null) {
                    addItem(item, list);
                } else {
                    List<MenuPlanItem> children = newParent.getChildren();
                    if (children == null) {
                        children = new ArrayList<>();
                        newParent.setChildren(children);
                    }
                    addItem(item, children);
                }
            } else {
                // 没有改变父节点 直接拷贝值
                oldItem.setLabel(item.getLabel());
                oldItem.setMenu(item.getMenu());
                oldItem.setIcon(item.getIcon());
                oldItem.setSeq(item.getSeq());
                oldItem.setHome(item.getHome());
            }

        }
    }

    // 删除节点
    public void delItem(long id) {
        MenuPlanItem parent = findParentById(id);
        if (parent == null) {
            removeById(id, list);
        } else {
            List<MenuPlanItem> children = parent.getChildren();
            if (!CommUtil.isEmpty(children)) {
                removeById(id, children);
            }
        }
    }

    // 转换成字符串
    public String toContentStr() {
        return JsonUtil.encodeString(list);
    }

    // 根据id找节点
    public MenuPlanItem findById(long id) {
        if (id <= 0) {
            return null;
        }
        return findById(id, list);
    }

    // 根据id找父节点
    public MenuPlanItem findParentById(long id) {
        if (id <= 0) {
            return null;
        }
        return findParentById(id, list);
    }

    // 获取子节点
    public List<MenuPlanItem> getChildren(long parentId) {
        if (parentId <= 0) {
            return list;
        }
        MenuPlanItem parent = findById(parentId);
        return parent == null ? new ArrayList<>(): parent.getChildren();
    }
    // 获取主页
    public List<MenuPlanItem> getHomeList(){
        List<MenuPlanItem> homeList = new ArrayList<>();
        findHome(list,homeList);
        return homeList;
    }
    private void findHome(List<MenuPlanItem> source,List<MenuPlanItem> homeList){
        if(CommUtil.isEmpty(source))return;
        for(MenuPlanItem item: source){
            if(item.getHome() == 1){
                homeList.add(item);
            }
            findHome(item.getChildren(),homeList);
        }
    }
    // 查询指定页面
    public void findPage(long pageId,List<MenuPlanItem> pageList){
        findPage(list,pageList,pageId);
    }
    // 查询指定页面
    private void findPage(List<MenuPlanItem> source,List<MenuPlanItem> pageList,long pageId){
        if(CommUtil.isEmpty(source))return;
        for(MenuPlanItem item: source){
            if(item.getMenu()>0L){
                Menu menu = MenuCache.getInstance().get(item.getMenu());
                if(menu!=null&& menu.getPageId().equalsIgnoreCase(String.valueOf(pageId))){
                    pageList.add(item);
                }
            }
            findPage(item.getChildren(),pageList,pageId);
        }
    }
    private MenuPlanItem findById(long id, List<MenuPlanItem> itemList) {
        if (CommUtil.isEmpty(itemList)) {
            return null;
        }
        for (MenuPlanItem item : itemList) {
            if (item.getId() == id) {
                return item;
            }
        }
        for (MenuPlanItem item : itemList) {
            if (!CommUtil.isEmpty(item.getChildren())) {
                MenuPlanItem rt = findById(id, item.getChildren());
                if (rt != null) {
                    return rt;
                }
            }
        }
        return null;
    }

    private MenuPlanItem findParentById(long id, List<MenuPlanItem> itemList) {
        if (CommUtil.isEmpty(itemList)) {
            return null;
        }
        for (MenuPlanItem item : itemList) {
            List<MenuPlanItem> children = item.getChildren();
            if (!CommUtil.isEmpty(children)) {
                for (MenuPlanItem i : children) {
                    if (i.getId() == id) {
                        return item;
                    }
                    if (!CommUtil.isEmpty(i.getChildren())) {
                        return findParentById(id, i.getChildren());
                    }
                }
            }
        }
        return null;
    }

    private void removeById(long id, List<MenuPlanItem> itemList) {
        if (itemList == null || itemList.size() <= 0) {
            return;
        }
        itemList.removeIf(item -> item.getId() == id);
    }

    private void addItem(MenuPlanItem item, List<MenuPlanItem> itemList) {
        if (itemList == null) {
            return;
        }
        itemList.add(item);
    }
}
