package cc.smtweb.system.bpm.web.design.preview;

import cc.smtweb.framework.core.annotation.SwParam;
import cc.smtweb.framework.core.annotation.SwService;
import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwConsts;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.db.vo.ModelCatalog;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.framework.core.util.CommUtil;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.util.TreeDataUtil;
import cc.smtweb.system.bpm.web.design.db.ModelCatalogCache;
import cc.smtweb.system.bpm.web.design.db.ModelProjectCache;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.ModelFormCache;
import cc.smtweb.system.bpm.web.sys.user.menu.MenuCache;
import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlan;
import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlanCache;
import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlanContent;
import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlanItem;
import cc.smtweb.system.bpm.web.sys.user.role.RoleHelper;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

@SwService
public class PreviewMenuTreeService {
    @SwParam
    private DbEngine dbEngine;

    public R treeAll(@SwParam("module") String module, UserSession us) {
        String prj_id = ModelProjectCache.getInstance().getIdByModule(module);
        if (!SwConsts.SysParam.SYS_DEBUG) {
            MenuVO home = new MenuVO();
            List<MenuVO> menuVOList = buildMenu(prj_id, module, us,home);
            if (!CommUtil.isEmpty(menuVOList)) {
                R r = R.success(menuVOList);
                if(home.getId()!=null&&home.getId()>0){
                    r.put("home",home);
                }
                return r;
            }else {
                return R.success(new ArrayList<>());
            }
        }
        List<ModelForm> listForm;
        if (StringUtils.isNotEmpty(prj_id)) {
            listForm = new ArrayList<>(ModelFormCache.getInstance().getFormsByPrj(Long.parseLong(prj_id)));
        } else {
            listForm = new ArrayList<>(ModelFormCache.getInstance().getAll());
        }
        listForm.sort((o1, o2) -> StringUtil.chineseCompare(o1.getTitle(), o2.getTitle()));
        if (listForm.isEmpty()) throw new BizException("此项目无页面设计！");

        List<MenuVO> list = new ArrayList<>();
        Map<Long, MenuVO> map = new HashMap<>();
        for (ModelForm form : listForm) {
            if (SwEnum.FormType.PAGE.value != form.getType()) continue;
            List<Long> parentLog = ModelCatalogCache.getInstance().getAllParent(form.getMcId());
            for (Long parent_id : parentLog) {
                if (map.containsKey(parent_id)) continue;
                ModelCatalog catalog = ModelCatalogCache.getInstance().get(parent_id);
                if (catalog == null || catalog.isEmpty()) continue;
                MenuVO menu = setMenuParent(parent_id, map, list);
                if (menu == null) continue;
                setMenuChildren(map.get(menu.getParentId()), menu);
            }
            MenuVO menu = new MenuVO();
            menu.setId(form.getId());
            menu.setName(form.getTitle());
            menu.setPath("/bpm/" + module + "." + form.getName());
            menu.setParentId(form.getMcId());
            setMenuChildren(map.get(form.getMcId()), menu);
        }

        MenuVO root = new MenuVO();
        root.setName("项目");
        root.setPath(module);
        root.setId(-1L);
        List<MenuVO> data = TreeDataUtil.buildTree(root, list, MenuVO.createTreeHandler());
        return  R.success(data);
    }

    public List<MenuVO> buildMenu(String prj_id, String module, UserSession us,MenuVO home) {
        Set<MenuPlan> set = RoleHelper.isAdmin(us.getUserId()) ? MenuPlanCache.getInstance().getByP(prj_id):RoleHelper.getMenuPlans(us.getUserId(),us.getPartyId());
        if (CommUtil.isEmpty(set)) {
            return new ArrayList<>();
        }
        MenuPlan menuPlan = set.iterator().next();
        MenuPlanContent mpc = new MenuPlanContent(menuPlan.getContent());
        List<MenuVO> list = new ArrayList<>();
        Set<Long> rightMenuIds = RoleHelper.getRoleMenuIds(us.getUserId() , us.getPartyId(),menuPlan.getId(), true);
        for(MenuPlanItem item : mpc.getHomeList()){
            long id = item.getId();
            if(rightMenuIds.contains(id)){
                home.setId(item.getId());
                home.setName(item.getLabel());
                home.setIcon(item.getIcon());
                home.setPath(MenuCache.getInstance().getPath(item.getMenu()));
                break;
            }
        }
        for (MenuPlanItem mp : mpc.getChildren(0)) {
            List<MenuVO> menuVOList = RoleHelper.isAdmin(us.getUserId())? buildMenu(-1,mp):buildMenuWithRight(-1, mp,rightMenuIds);
            if (menuVOList == null) continue;
            list.addAll(menuVOList);
        }
        MenuVO root = new MenuVO();
        root.setName("项目");
        root.setPath(module);
        root.setId(-1L);
        return TreeDataUtil.buildTree(root, list, MenuVO.createTreeHandler());
    }

    private List<MenuVO> buildMenu(long parent_id, MenuPlanItem mp) {
        if (mp == null) return null;
        List<MenuVO> list = new ArrayList<>();
        MenuVO menu = new MenuVO();
        menu.setId(mp.getId());
        menu.setName(mp.getLabel());
        menu.setIcon(mp.getIcon());
        menu.setPath(MenuCache.getInstance().getPath(mp.getMenu()));
        menu.setParentId(parent_id);
        List<MenuVO> child = new ArrayList<>();
        if (!CommUtil.isEmpty(mp.getChildren())) {
            for (MenuPlanItem cmp : mp.getChildren()) {
                List<MenuVO> m = buildMenu(menu.getId(), cmp);
                if (m == null) continue;
                child.addAll(m);
            }
        }
        menu.setChildren(child);
        list.add(menu);
        return list;
    }
    private List<MenuVO> buildMenuWithRight(long parent_id, MenuPlanItem mp,Set<Long> rightMenuIds) {
        if (mp == null || !rightMenuIds.contains(mp.getId())) return null;
        List<MenuVO> list = new ArrayList<>();
        MenuVO menu = new MenuVO();
        menu.setId(mp.getId());
        menu.setName(mp.getLabel());
        menu.setIcon(mp.getIcon());
        menu.setPath(MenuCache.getInstance().getPath(mp.getMenu()));
        menu.setParentId(parent_id);
        List<MenuVO> child = new ArrayList<>();
        if (!CommUtil.isEmpty(mp.getChildren())) {
            for (MenuPlanItem cmp : mp.getChildren()) {
                List<MenuVO> m = buildMenuWithRight(menu.getId(), cmp,rightMenuIds);
                if (m == null) continue;
                child.addAll(m);
            }
        }
        menu.setChildren(child);
        list.add(menu);
        return list;
    }
    private MenuVO setMenuParent(Long parent_id, Map<Long, MenuVO> map, List<MenuVO> list) {
        MenuVO parent = map.get(parent_id);
        if (parent != null) return parent;

        ModelCatalog parentBean = ModelCatalogCache.getInstance().get(parent_id);
        if (parentBean == null) return null;
        parent = map.get(parentBean.getId());
        if (parent != null) return parent;
        parent = new MenuVO();
        parent.setId(parentBean.getId());
        parent.setName(parentBean.getName());
        parent.setPath("");
        parent.setParentId(parentBean.getParentId());
        if (parentBean.getParentId() == -1) {
            list.add(parent);
        }
        map.put(parentBean.getId(), parent);
        setMenuParent(parentBean.getParentId(), map, list);
        return parent;
    }

    private void setMenuChildren(MenuVO parent, MenuVO child) {
        if (parent == null) return;
        List<MenuVO> childs = parent.getChildren();
        if (childs == null) {
            childs = new ArrayList<>();
            parent.setChildren(childs);
        }
        childs.add(child);
    }
}
