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

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.common.SwEnum;
import cc.smtweb.framework.core.common.SwMap;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.exception.BizException;
import cc.smtweb.framework.core.mvc.service.SwListData;
import cc.smtweb.framework.core.session.UserSession;
import cc.smtweb.framework.core.util.StringUtil;
import cc.smtweb.system.bpm.web.common.BpmEnum;
import cc.smtweb.system.bpm.web.design.form.ModelForm;
import cc.smtweb.system.bpm.web.design.form.ModelFormCache;
import cc.smtweb.system.bpm.web.design.form.define.PageDataset;
import cc.smtweb.system.bpm.web.design.form.define.PageDatasetField;
import cc.smtweb.system.bpm.web.engine.dynPage.*;
import cc.smtweb.system.bpm.web.sys.user.dataRight.DataRightDefineCache;
import cc.smtweb.system.bpm.web.sys.user.dataRightGroup.DataRightGroupCache;
import cc.smtweb.system.bpm.web.sys.user.menu.Menu;
import cc.smtweb.system.bpm.web.sys.user.menu.MenuCache;
import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlanCache;
import cc.smtweb.system.bpm.web.sys.user.menuPlan.MenuPlanItem;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @Author: tanghp
 * @Date: 2022-08-01 17:47
 * @Desc:
 */
public class RoleHandler {
    private final static String ROLE_FUNC = "roleFuncCombo";
    private final static String ROLE_Field = "roleFieldCombo";
    private final static String ROLE_DATA = "roleDataList";
    private final static String RIGHT_DATA = "rightData";

    static class RoleSaveHandler extends DynPageSaveHandler {

        /**
         * 保存指定数据集操作，入参：{pageId,dataset:"", data:{form:{},list: {total:0,rows:[]}}, filter:{}}
         */
        public R saveOne() {
            //数据集
            String dbName = params.readString("dataset");
            SwMap filter = params.readMap("filter");
            //待保存数据
            SwMap data = params.readMap("data");
            if (data == null) throw new BizException("没有收到待保存的的数据：" + dbName + "！");
            //对应的数据集定义
            PageDataset pageDataSet = findDataset(dbName);
            if (pageDataSet == null) throw new BizException("没有找到指定的的数据集定义：" + dbName + "！");
            if (pageDataSet.name.equals(RIGHT_DATA)) {
                long role_id = filter.readLong("role_id");
                long mp_id = filter.readLong("mp_id");
                if (role_id <= 0) return R.error("未指定角色！");
                SwMap formData = data.readMap("form");
                Set<Long> set = formData.readLongSet("menu");
                //if (CommUtil.isEmpty(set)) return R.error("未选择菜单！");
                Role role = RoleCache.getInstance().get(role_id);
                RoleRightContent rc = new RoleRightContent(role.getPrivilege());
                rc.resetItem();
                for (Long menu_id : set) {
                    MenuPlanItem item = MenuPlanCache.getInstance().getById(role.getSmpId(), menu_id);
                    RoleRight right = rc.getRoleRight(item.getId());
                    if (right == null) {
                        right = new RoleRight();
                        right.setId(item.getId());
                        right.setMenuId(item.getMenu());
                    }
                    right.setMenu(1);
                    rc.saveItem(right);
                }
                if (mp_id > 0) {
                    MenuPlanItem item = MenuPlanCache.getInstance().getById(role.getSmpId(), mp_id);
                    RoleRight right = rc.getRoleRight(item.getId());
                    if (right == null) {
                        right = new RoleRight();
                        right.setId(item.getId());
                        right.setMenuId(item.getMenu());
                    }
                    right.setMenu(1);
                    right.setFunc(formData.readStringSet("func"));
                    right.setData(formData.readListMap("data"));
                    if (item.getMenu() > 0L)
                        right.setField(MenuCache.getInstance().get(item.getMenu()).getRightSet(BpmEnum.MenuRightType.FIELD.value), formData.readStringSet("write"), formData.readStringSet("read"));
                    rc.saveItem(right);
                }
                role.setPrivilege(rc.toContentStr());
                DbEngine.getInstance().findDao(Role.ENTITY_NAME).updateEntity(role);
                RoleCache.getInstance().put(role);
                return R.success(DynRetBean.createBean(formData));
            }
            return super.saveOne();
        }
    }

    static class RoleLoadHandle extends DynPageLoadHandler {

        @Override
        public DynPageProvider getProvider() {
            return new RightDataProvider();
        }

        @Override
        public DynPageListHandler getListWorker(SwMap filter, PageDataset pageDataSet) {
            switch (pageDataSet.name) {
                case ROLE_FUNC:
                    return new RoleFuncListHandle(form.getId(), filter, pageDataSet);
                case ROLE_Field:
                    return new RoleFieldListHandle(form.getId(), filter, pageDataSet);
                case ROLE_DATA:
                    return new RoleDataListHandle(form.getId(), filter, pageDataSet);
            }
            return super.getListWorker(filter, pageDataSet);
        }


    }

    static class RightDataProvider extends DynPageProvider {
        @Override
        public SwMap loadData(SwMap filter, PageDataset pageDataSet) {
            if (pageDataSet.name.equals(RIGHT_DATA)) {
                SwMap bean = new SwMap();
                long role_id = filter.readLong("role_id");
                long mp_id = filter.readLong("mp_id");
                if (role_id <= 0) return bean;
                Role role = RoleCache.getInstance().get(role_id);
                RoleRightContent rc = new RoleRightContent(role.getPrivilege());
                if (mp_id <= 0) {
                    bean.put("menu", rc.getMenuRight());
                    return bean;
                }
                MenuPlanItem item = MenuPlanCache.getInstance().getById(role.getSmpId(), mp_id);
                if (item == null) return bean;
                bean.put("menu", rc.getMenuRight());
                bean.put("func", rc.getFuncRight(item.getId()));
                bean.put("read", rc.getFieldRight(item.getId(), 1));
                bean.put("write", rc.getFieldRight(item.getId(), 2));
                return bean;
            }
            return super.loadData(filter, pageDataSet);
        }
    }

    static class RoleFieldListHandle extends DynPageListHandler {

        public RoleFieldListHandle(long pageId, SwMap filter, PageDataset pageDataSet) {
            super(pageId, filter, pageDataSet);
        }

        private String getFieldName(ModelForm mf, String field) {
            PageDatasetField df = mf.getField(field);
            if (df == null) return null;
            return df.label;
        }

        @Override
        public SwListData buildListData() {
            List<SwMap> list = new ArrayList<>();
            long role_id = filter.readLong("role_id");
            long mp_id = filter.readLong("mp_id");
            if (role_id <= 0 || mp_id <= 0) return SwListData.create(list, 0);
            Role role = RoleCache.getInstance().get(role_id);
            MenuPlanItem item = MenuPlanCache.getInstance().getById(role.getSmpId(), mp_id);
            if (item == null) return SwListData.create(list, 0);
            Menu menu = MenuCache.getInstance().get(item.getMenu());
            if (menu == null) return SwListData.create(list, 0);
            ModelForm mf = ModelFormCache.getInstance().get(menu.getPageId());
            for (String f : menu.getRightSet(BpmEnum.MenuRightType.FIELD.value)) {
                String name = getFieldName(mf, f);
                if (name == null) continue;
                SwMap row = new SwMap();
                row.put("f_id", f);
                row.put("f_name", name);
                list.add(row);
            }
            return SwListData.create(list, 0);
        }

        @Override
        public R getTotal() {
            return R.success(buildListData().getTotal());
        }
    }

    static class RoleFuncListHandle extends DynPageListHandler {

        public RoleFuncListHandle(long pageId, SwMap filter, PageDataset pageDataSet) {
            super(pageId, filter, pageDataSet);
        }

        @Override
        public SwListData buildListData() {
            List<SwMap> list = new ArrayList<>();
            long role_id = filter.readLong("role_id");
            long mp_id = filter.readLong("mp_id");
            if (role_id <= 0 || mp_id <= 0) return SwListData.create(list, 0);
            Role role = RoleCache.getInstance().get(role_id);
            MenuPlanItem item = MenuPlanCache.getInstance().getById(role.getSmpId(), mp_id);
            if (item == null) return SwListData.create(list, 0);
            Menu menu = MenuCache.getInstance().get(item.getMenu());
            if (menu == null) return SwListData.create(list, 0);
            for (String f : menu.getRightSet(BpmEnum.MenuRightType.FUNC.value)) {
                if (StringUtil.isEmpty(f)) continue;
                SwMap row = new SwMap();
                row.put("f_id", f);
                row.put("f_name", BpmEnum.MenuFuncRight.instance.getName(f));
                list.add(row);
            }
            return SwListData.create(list, 0);
        }

        @Override
        public R getTotal() {
            return R.success(buildListData().getTotal());
        }
    }

    static class RoleDataListHandle extends DynPageListHandler {

        public RoleDataListHandle(long pageId, SwMap filter, PageDataset pageDataSet) {
            super(pageId, filter, pageDataSet);
        }

        @Override
        public SwListData buildListData() {
            List<SwMap> list = new ArrayList<>();
            long role_id = filter.readLong("role_id");
            long mp_id = filter.readLong("mp_id");
            if (role_id <= 0 || mp_id <= 0) return SwListData.create(list, 0);
            Role role = RoleCache.getInstance().get(role_id);
            MenuPlanItem item = MenuPlanCache.getInstance().getById(role.getSmpId(), mp_id);
            if (item == null) return SwListData.create(list, 0);
            Menu menu = MenuCache.getInstance().get(item.getMenu());
            if (menu == null) return SwListData.create(list, 0);
            RoleRightContent rc = new RoleRightContent(role.getPrivilege());
            Map<String,Map<String, Object>> data = rc.getDataRight(item.getId());

            //遍历该菜单拥有的数据权限，再把已配置的菜单数据权限填充进去
            for (String f : menu.getRightSet(BpmEnum.MenuRightType.DATA.value)) {
                if (StringUtil.isEmpty(f)) continue;
                SwMap row = new SwMap();
                row.put("key", f);
                row.put("key_text", DataRightDefineCache.getInstance().get(f).getName());
                if (data.containsKey(f)) {
                    Map<String,Object> right = data.get(f);
                    row.put("value", right.get("value"));
                    row.put("value_text", DataRightGroupCache.getInstance().get(right.get("value").toString()).getName());
                }
                list.add(row);
            }
            return SwListData.create(list, 0);
        }

        @Override
        public R getTotal() {
            return R.success(buildListData().getTotal());
        }
    }
}
