package cn.ibizlab.core.extensions.service;


import cn.ibizlab.core.uaa.service.ISYS_PERMISSIONService;
import cn.ibizlab.core.uaa.service.ISYS_PSAPPMENUITEMService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

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

@Service
@Slf4j
public class UAACoreService {
    @Autowired
    private ISYS_PERMISSIONService isys_permissionService;
    @Autowired
    private ISYS_PSAPPMENUITEMService isys_psappmenuitemService;
    /**
     * 获取用户菜单
     *
     * @return
     */
    public JSONArray getAppMenu() {
        // 用户所在系统id,R7的AuthenticationUser中已经没有systemid了
//        String systemid= AuthenticationUser.getAuthenticationUser().getSystemid();
        String systemid = null;

        StringBuilder nPermissionSQL = new StringBuilder();
        nPermissionSQL.append("SELECT ");
        nPermissionSQL.append(" t.SYS_PERMISSIONID as sys_permissionid, ");
        nPermissionSQL.append(" t.SYS_PERMISSIONNAME as sys_permissionname, ");
//        nPermissionSQL.append(" t1.PERMISSIONID as permissionid, ");
        nPermissionSQL.append(" t1.PSAPPMENUITEMID as permissionid, ");
//        nPermissionSQL.append(" t1.P_PERMISSIONID as p_permissionid, ");
        nPermissionSQL.append(" t1.PSAPPPMENUITEMID as p_permissionid, ");
        nPermissionSQL.append(" t1.PSAPPID as psappid, ");
        nPermissionSQL.append(" t1.PSAPPNAME as psappname, ");
        nPermissionSQL.append(" t1.PSAPPMENUID as psappmenuid, ");
        nPermissionSQL.append(" t1.PSAPPMENUNAME as psappmenuname, ");
        nPermissionSQL.append(" t1.PSSYSTEMID as systemid ");
        nPermissionSQL.append(" FROM IBZPERMISSION t");
        nPermissionSQL.append(" INNER JOIN IBZPSAPPMENUITEM t1 ON t.SYS_PERMISSIONID = t1.SYS_PSAPPMENUITEMID and t.enable =1");

        StringBuilder permissionSQL = new StringBuilder();
        permissionSQL.append("SELECT ");
        permissionSQL.append(" t.SYS_PERMISSIONID as sys_permissionid,");
        permissionSQL.append(" t.SYS_PERMISSIONNAME as sys_permissionname,");
//       permissionSQL.append(" t1.PERMISSIONID as permissionid, ");
        permissionSQL.append(" t1.PSAPPMENUITEMID as psappmenuitemid, ");
//        permissionSQL.append(" t1.P_PERMISSIONID as p_permissionid, ");
        permissionSQL.append(" t1.PSAPPPMENUITEMID as psapppmenuitemid, ");
        permissionSQL.append(" t1.PSAPPID as psappid,");
        permissionSQL.append(" t1.PSAPPNAME as psappname,");
        permissionSQL.append(" t1.PSAPPMENUID as psappmenuid,");
        permissionSQL.append(" t1.PSAPPMENUNAME as psappmenuname,");
        permissionSQL.append(" t1.PSSYSTEMID as systemid");
        permissionSQL.append(" FROM IBZPERMISSION t");
        permissionSQL.append(" INNER JOIN IBZPSAPPMENUITEM t1 ON t.SYS_PERMISSIONID = t1.SYS_PSAPPMENUITEMID and t.systemid='" + systemid + "' and t.enable =1");


        List<JSONObject> permissions;
        if (StringUtils.isEmpty(systemid)) {
            permissions = isys_psappmenuitemService.select(nPermissionSQL.toString(),null);
        } else {
            permissions = isys_psappmenuitemService.select(permissionSQL.toString(),null);
        }

        JSONArray treeNode = new JSONArray();
        if (permissions.size() > 0) {
            treeNode = this.transferAppMenuToELTree(permissions);
        }

        return treeNode;
    }

    /**
     * 用于将资源表中菜单数据转换成饿了么树格式数据
     *
     * @param
     * @return
     */
    private JSONArray transferAppMenuToELTree(List<JSONObject> appMenuDatas) {
        Map<String, String> appKeyMap = new HashMap<>();
        Map<String, String> appMenuKeyMap = new HashMap<>();
        JSONObject groupByMenuObj = this.groupByAppMenu(appMenuDatas, appKeyMap, appMenuKeyMap);//将数据库数据进行分组
        JSONArray elTreeObj = transferAppMenuToELTree(groupByMenuObj, appKeyMap, appMenuKeyMap);//将分组后的数据转换成饿了么树格式数据
        return elTreeObj;
    }

    /**
     * 将数据库中的菜单数据进行分组
     *
     * @param dbdata
     * @return
     */
    private JSONObject groupByAppMenu(List<JSONObject> dbdata, Map<String, String> appKeyMap, Map<String, String> appMenuKeyMap) {

        JSONObject permission_app = new JSONObject(); //顶级模块数据
        for (JSONObject obj : dbdata) {
            String str_app = String.format("IBIZAPP-%s", obj.get("psappid"));
            String str_appName = String.format("%s", obj.get("psappname"));
            String str_appMenu = String.format("IBIZMENU-%s", obj.get("psappmenuid"));
            String str_appMenuName = String.format("%s", obj.get("psappmenuname"));
            String systemId = String.format("%s", obj.get("systemid"));

//            String sys_permissionId = DigestUtils.md5DigestAsHex(String.format("%s%s", systemId, obj.get("permissionid")).getBytes());
            String permissionId = String.format("%s", obj.get("permissionid"));
            String sys_permissionId = String.format("%s", obj.get("sys_permissionid"));
            String p_sys_permissionId = "";

            if (!StringUtils.isEmpty(obj.get("p_permissionid"))) {
//                p_sys_permissionId = DigestUtils.md5DigestAsHex(String.format("%s%s", systemId, obj.get("p_permissionid")).getBytes());
                p_sys_permissionId = String.format("%s",obj.get("p_permissionid"));
            }

            JSONObject cur_app = new JSONObject();
            JSONArray cur_app_menu = new JSONArray();

            if (permission_app.containsKey(str_app))//合并前端应用
                cur_app = permission_app.getJSONObject(str_app);

            if (cur_app.containsKey(str_appMenu))//合并菜单
                cur_app_menu = cur_app.getJSONArray(str_appMenu);

            JSONObject permission = new JSONObject();
            permission.put("id", permissionId);
            permission.put("sys_permissionId", sys_permissionId);
            permission.put("pid", p_sys_permissionId);
            permission.put("label", obj.get("sys_permissionname"));

            cur_app_menu.add(permission);
            cur_app.put(str_appMenu, cur_app_menu);
            permission_app.put(str_app, cur_app);

            //应用名称映射表
            if (!appKeyMap.containsKey(str_app))
                appKeyMap.put(str_app, str_appName);

            //应用菜单名称映射表
            if (!appMenuKeyMap.containsKey(str_appMenu))
                appMenuKeyMap.put(str_appMenu, str_appMenuName);

        }
        return permission_app;
    }

    /**
     * 将以分组的树节点转换成饿了么格式的树
     *
     * @param sysApps
     * @return
     */
    private JSONArray transferAppMenuToELTree(JSONObject sysApps, Map<String, String> appKeyMap, Map<String, String> appMenuKeyMap) {
        JSONArray appMenuArr = new JSONArray();
        Set<String> sysAppkeys = sysApps.keySet();
        for (String sysAppkey : sysAppkeys) {
            Object appMenu = sysApps.get(sysAppkey);
            if (appMenu instanceof JSONObject) {
                JSONArray appChildMenuItemArr = transferAppMenuToELTree((JSONObject) appMenu, appKeyMap, appMenuKeyMap); //递归遍历输出下级节点信息
                JSONObject appMenuItem = new JSONObject();
                appMenuItem.put("id", sysAppkey);
                sysAppkey = praseLabel(sysAppkey, appKeyMap, appMenuKeyMap);
                appMenuItem.put("label", sysAppkey);
                appMenuItem.put("children", appChildMenuItemArr);
                appMenuArr.add(appMenuItem);
            } else {
                if (appMenu instanceof JSONArray) {
                    JSONArray appMenuItemArr = sysApps.getJSONArray(sysAppkey);
                    JSONObject appMenuItem = new JSONObject();
                    appMenuItem.put("id", sysAppkey);
                    sysAppkey = praseLabel(sysAppkey, appKeyMap, appMenuKeyMap);
                    appMenuItem.put("label", sysAppkey);
                    appMenuItem.put("children", getTreesData(appMenuItemArr, ""));
                    appMenuArr.add(appMenuItem);
                }
            }
        }
        return appMenuArr;
    }

    /**
     * 递归遍历树节点
     *
     * @param PermissionNodes
     * @param parentId
     * @return
     */
    private JSONArray getTreesData(JSONArray PermissionNodes, Object parentId) {
        JSONArray treeDatas = new JSONArray();
        for (int a = 0; a < PermissionNodes.size(); a++) {
            JSONObject PermissionNode = PermissionNodes.getJSONObject(a);
            String p_permissionId = PermissionNode.getString("pid");
            if (StringUtils.isEmpty(p_permissionId)) {
                p_permissionId = "";
            }
            if (parentId.equals(p_permissionId)) {
                JSONArray childCodeItem = getTreesData(PermissionNodes, PermissionNode.getString("id"));
                if (childCodeItem.size() > 0) {
                    PermissionNode.put("children", childCodeItem);
                }
                treeDatas.add(PermissionNode);
            }
        }
        return treeDatas;
    }

    /**
     * 拿到带有IBIZAPP-或IBIZMENU-标识的key把标记移除
     */
    private String praseLabel(String key, Map<String, String> appKeyMap, Map<String, String> appMenuKeyMap) {
        if (key.startsWith("IBIZAPP-")) {
            if (appKeyMap.containsKey(key)) {
                key = appKeyMap.get(key);
            }
            key = key.replace("IBIZAPP-", "");
        }
        if (key.startsWith("IBIZMENU-")) {
            if (appMenuKeyMap.containsKey(key)) {
                key = appMenuKeyMap.get(key);
            }
            key = key.replace("IBIZMENU-", "");
        }
        return key;
    }

    /**
     * 获取数据操作标识
     *
     * @return
     */
    public JSONArray getDEOppriv() {
        JSONArray treeNode = new JSONArray();
        StringBuilder permissionsSql = new StringBuilder();
        permissionsSql.append("select ");
        permissionsSql.append(" t.SYS_PERMISSIONID as sys_permissionid, ");
        permissionsSql.append(" t.SYS_PERMISSIONNAME as sys_permissionname, ");
        permissionsSql.append(" t1.PSSYSMODULEID as pssysmoduleid, ");
        permissionsSql.append(" t1.PSSYSMODULENAME as pssysmodulename, ");
        permissionsSql.append(" t1.PSDATAENTITYID as psdataentityid, ");
        permissionsSql.append(" t1.PSDATAENTITYNAME as psdataentityname, ");
        permissionsSql.append(" t1.Pssourceid as pssourceid, ");
        permissionsSql.append(" t1.Pssourcename as pssourcename,");
        permissionsSql.append(" t1.PSDEDATARANGEID as psdedatarangeid, ");
        permissionsSql.append(" t1.PSDEDATARANGENAME as psdedatarangename,");
        permissionsSql.append(" t1.PSSYSTEMID as systemid ");
        permissionsSql.append(" FROM IBZPERMISSION t");
        permissionsSql.append(" INNER JOIN IBZPSDEOPPRIV t1 ON t.SYS_PERMISSIONID = t1.SYS_PSDEOPPRIVID");
        List<JSONObject> permissions = isys_permissionService.select(permissionsSql.toString(),null);

        if (permissions.size() > 0) {
            treeNode = this.transferDataCapabilityToELTree(permissions);
        }

        return treeNode;
    }


    /**
     * 用于将资源表中数据能力数据转换成饿了么树格式数据
     *
     * @param deCapabilityDatas
     * @return
     */
    public JSONArray transferDataCapabilityToELTree(List<JSONObject> deCapabilityDatas) {
        Map<String, String> opprivTreeNameMap = new HashMap<>();
        JSONObject groupByMenuObj = groupByDataCapability(deCapabilityDatas, opprivTreeNameMap);//将数据库数据进行分组
        JSONArray elTreeObj = transferDataCapabilityToELTree(groupByMenuObj, opprivTreeNameMap);//将分组后的数据转换成饿了么树格式数据
        return elTreeObj;
    }

    /**
     * 将数据库中的数据能力数据进行分组
     *
     * @param deCapabilityDatas
     * @return
     */
    private JSONObject groupByDataCapability(List<JSONObject> deCapabilityDatas, Map<String, String> opprivTreeNameMap) {
        JSONObject root_system = new JSONObject(); //顶级系统数据
        JSONObject permission_moudle = new JSONObject(); //次级模块数据
        for (JSONObject obj : deCapabilityDatas) {
            JSONObject jobj = new JSONObject();
            jobj.putAll(obj);

            String str_systemid = jobj.getString("systemid");

            String str_moudle = jobj.getString("pssysmoduleid");
            String str_moudle_name = jobj.getString("pssysmodulename");
            String str_entity = jobj.getString("psdataentityid");
            String str_entity_name = jobj.getString("psdataentityname");
            String str_dataset = jobj.getString("pssourceid");
            String str_dataset_name = jobj.getString("pssourcename");
            String str_datarange = jobj.getString("psdedatarangeid");
            String str_datarange_name = jobj.getString("psdedatarangename");
            String str_permissionname = jobj.getString("sys_permissionname");
            String str_permissionid = jobj.getString("sys_permissionid");

            JSONObject cur_system = new JSONObject();
            JSONObject cur_moudle = new JSONObject();
            JSONObject cur_entity = new JSONObject();
            JSONObject cur_dataset = new JSONObject();
            JSONArray cur_data_range = new JSONArray();

            if (root_system.containsKey(str_systemid))// 系统合并
                cur_system = root_system.getJSONObject(str_systemid);

            if (permission_moudle.containsKey(str_moudle))//模块合并
                cur_moudle = permission_moudle.getJSONObject(str_moudle);

            if (cur_moudle.containsKey(str_entity))//实体合并
                cur_entity = cur_moudle.getJSONObject(str_entity);

            if (cur_entity.containsKey(str_dataset))//数据集合并
                cur_dataset = cur_entity.getJSONObject(str_dataset);

            if (cur_dataset.containsKey(str_datarange))//数据范围合并
                cur_data_range = cur_dataset.getJSONArray(str_datarange);

            JSONObject permission = new JSONObject();
            permission.put("id", str_permissionid);
            permission.put("label", str_permissionname);

            cur_data_range.add(permission);

            cur_dataset.put(str_datarange, cur_data_range);

            cur_entity.put(str_dataset, cur_dataset);

            cur_moudle.put(str_entity, cur_entity);

            permission_moudle.put(str_moudle, cur_moudle);


            //构造树节点名称集合
            if (!opprivTreeNameMap.containsKey(str_systemid)) {
                opprivTreeNameMap.put(str_systemid, "SYSTEM");
            }
            if (!opprivTreeNameMap.containsKey(str_moudle)) {
                opprivTreeNameMap.put(str_moudle, str_moudle_name);
            }
            if (!opprivTreeNameMap.containsKey(str_entity)) {
                opprivTreeNameMap.put(str_entity, str_entity_name);
            }
            if (!opprivTreeNameMap.containsKey(str_dataset)) {
                opprivTreeNameMap.put(str_dataset, str_dataset_name);
            }
            if (!opprivTreeNameMap.containsKey(str_datarange_name)) {
                opprivTreeNameMap.put(str_datarange, str_datarange_name);
            }

        }

        return permission_moudle;
    }

    /**
     * 权限树递归
     *
     * @param childNode
     * @return
     */
    private JSONArray transferDataCapabilityToELTree(JSONObject childNode, Map<String, String> opprivTreeNameMap) {
        JSONArray array = new JSONArray();
        Set<String> keys = childNode.keySet();
        for (String key : keys) {
            Object obj = childNode.get(key);
            if (obj instanceof JSONObject) {
                JSONArray childArr = transferDataCapabilityToELTree(childNode.getJSONObject(key), opprivTreeNameMap); //递归遍历输出下级节点信息
                JSONObject childNodeObj = new JSONObject();
                childNodeObj.put("id", key);
                childNodeObj.put("label", opprivTreeNameMap.get(key));
                childNodeObj.put("children", childArr);
                array.add(childNodeObj);
            } else {
                if (obj instanceof JSONArray) {

                    JSONArray permissionArr = new JSONArray();
                    JSONArray jsonArray = childNode.getJSONArray(key);
                    for (int a = 0; a < jsonArray.size(); a++) {   //最后一层
                        JSONObject permissionObj = jsonArray.getJSONObject(a);
                        JSONObject transPermissionObj = new JSONObject();
                        transPermissionObj.put("id", permissionObj.getString("id"));
                        transPermissionObj.put("label", permissionObj.getString("label"));
                        permissionArr.add(transPermissionObj);
                    }

                    JSONObject childNodeObj = new JSONObject();
                    childNodeObj.put("id", key);
                    childNodeObj.put("label", opprivTreeNameMap.get(key));
                    childNodeObj.put("children", permissionArr);
                    array.add(childNodeObj);
                }
            }
        }
        return array;
    }

}
