package com.engine.organization.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.engine.core.impl.Service;
import com.engine.organization.service.OrgChartService;
import com.engine.organization.util.HasRightUtil;
import com.engine.organization.util.db.DBType;
import org.apache.commons.lang3.StringUtils;
import weaver.conn.RecordSet;
import weaver.hrm.User;

import java.util.*;

/**
 * @className: OrgChartServiceImpl
 * @author: dengjp
 * @date: 2022/7/7
 * @description: 组织架构图ServiceImpl
 **/
public class OrgChartServiceImpl extends Service implements OrgChartService {

    private RecordSet grs = new RecordSet();

    private static final String COMPANY_RIGHT = "OrgChart:All";
    private static final String USER_RIGHT = "OrgPerspective:All";

    @Override
    public Map<String, Object> getOptionCondition(Map<String, Object> request2Map, User user) {
        Map<String, Object> result = new HashMap<>();
        RecordSet rs = new RecordSet();

        rs.executeQuery("select id, companyname from HrmCompanyVirtual order by id");
        List<Map<String, Object>> fclasslist = new ArrayList<>();
        Map<String, Object> defaultItem = new HashMap<>();
        defaultItem.put("id", "0");
        defaultItem.put("companyname", "行政维度");
        fclasslist.add(defaultItem);
        while (rs.next()) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", rs.getString("id"));
            item.put("companyname", rs.getString("companyname"));
            fclasslist.add(item);
        }

        rs.executeQuery("select id, fnumber, fname from jcl_org_map where ftype in (0, 1) order by ftype , id ");
        List<Map<String, Object>> companylist = new ArrayList<>();
        Map<String, Object> defaultCompanyItem = new HashMap<>();
        companylist.add(defaultCompanyItem);
        while (rs.next()) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", rs.getString("id"));
            item.put("fnumber", rs.getString("fnumber"));
            item.put("fname", rs.getString("fname"));
            companylist.add(item);
        }
        result.put("api_status", true);
        result.put("fclasslist", fclasslist);
        result.put("companylist", companylist);
        return result;
    }

    private String companyDateWhereSql(Map<String, Object> request2Map) {
        String date = (String) request2Map.get("date");  // 数据日期
        if (StringUtils.isBlank(date)) {
            date = DateUtil.format(DateUtil.offset(new Date(), DateField.DAY_OF_MONTH, 1), "yyyy-MM-dd");
        }

        String fclass = (String) request2Map.get("fclass");  // 维度


        String fisvitual = (String) request2Map.get("fisvitual");  // 是否显示虚拟组织
        if (StringUtils.isBlank(fisvitual)) {
            fisvitual = "0";
        }

        String whereSql = " where 1 = 1 ";
        if (DBType.isOracle()) {
            whereSql += " and ((fdatebegin <=  to_date('" + date + "','yyyy-MM-DD') and fdateend >= to_date('" + date + "','yyyy-MM-DD')) or (fdatebegin <= to_date('" + date + "','yyyy-MM-DD') and fdateend is null )) ";
        } else {
            whereSql += " and ((fdatebegin <= '" + date + "' and fdateend >= '" + date + "') or (fdatebegin <= '" + date + "' and fdateend is null )) ";
        }
        whereSql += " and fclass = " + fclass + " ";

        if ("0".equals(fisvitual)) {
            whereSql += " and fisvitual = 0 ";
        } else {
            whereSql += " and fisvitual in (0, 1) ";
        }

        whereSql += " and ftype in (0 , 1 ,2) ";
        return whereSql;
    }

    @Override
    public Map<String, Object> getCompanyData(Map<String, Object> request2Map, User user) {
        Map<String, Object> result = new HashMap<>();
        boolean hasRight = HasRightUtil.hasRight(user, COMPANY_RIGHT, true);
        result.put("hasRight", hasRight);
        if (!hasRight) {
            return result;
        }

        String root = (String) request2Map.get("root");  // 根节点
        String level = (String) request2Map.get("level"); // 显示层级
        if (StringUtils.isBlank(level)) {
            level = "3";
        }
        String whereSql = companyDateWhereSql(request2Map);

        String whereItemSql = " ";
        if ("0".equals(root)) { // 集团的情况
            whereItemSql += " and ftype = 0 ";
        } else {
            whereItemSql += " and id = '" + root + "' ";
        }

        // 获取根节点
        RecordSet rs = new RecordSet();
        rs.executeQuery("select id, fname, ftype, fparentid, fnumber from jcl_org_map " + whereSql + whereItemSql);
        List<Map<String, Object>> list = new ArrayList<>();
        String id = null;
        if (rs.next()) {
            Map<String, Object> item = new HashMap<>();
            id = rs.getString("id");
            item.put("id", rs.getString("id"));
            item.put("fname", rs.getString("fname"));
            item.put("ftype", rs.getString("ftype"));
            item.put("fnumber", rs.getString("fnumber"));
            item.put("parentId", null);
            item.put("expand", "1");
            item.put("hasChildren", hasChildren(rs.getString("id"), true));
            list.add(item);
        }

        int currentLevel = 1;
        if (currentLevel + 1 <= Integer.parseInt(level)) {
            findCompanyItemByParantId(id, currentLevel + 1, level, rs, list, whereSql, true);
        }

        result.put("api_status", true);
        result.put("data", list);
        return result;
    }

    private void findCompanyItemByParantId(String id, int currentLevel, String level, RecordSet rs, List<Map<String, Object>> list, String whereSql, boolean expand) {
        rs.executeQuery("select id, fname, ftype, fparentid,fobjid,fecid,fnumber from jcl_org_map " + whereSql + " and fparentid = " + id);
        List<Map<String, Object>> currentList = new ArrayList<>();
        while (rs.next()) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", rs.getString("id"));
            item.put("fname", rs.getString("fname"));
            item.put("ftype", rs.getString("ftype"));
            item.put("parentId", rs.getString("fparentid"));
            item.put("fnumber", rs.getString("fnumber"));
            item.put("fobjid", rs.getString("fobjid"));
            item.put("fecid", rs.getString("fecid"));
            item.put("expand", expand ? "1" : "0");
            item.put("hasChildren", hasChildren(rs.getString("id"), true));
            currentList.add(item);
        }

        list.addAll(currentList);

        for (Map<String, Object> stringObjectMap : currentList) {
            if (currentLevel + 1 <= Integer.parseInt(level)) {
                findCompanyItemByParantId((String) stringObjectMap.get("id"), currentLevel + 1, level, rs, list, whereSql, true);
            } else if (currentLevel == Integer.parseInt(level)) {
                findCompanyItemByParantId((String) stringObjectMap.get("id"), currentLevel + 1, level, rs, list, whereSql, false);
            }
        }

    }

    private String userWhereSql(Map<String, Object> request2Map) {
        String date = (String) request2Map.get("date");  // 数据日期
        if (StringUtils.isBlank(date)) {
            date = DateUtil.format(DateUtil.offset(new Date(), DateField.DAY_OF_MONTH, 1), "yyyy-MM-dd");
        }

        String fclass = (String) request2Map.get("fclass");  // 维度


        String fisvitual = (String) request2Map.get("fisvitual");  // 是否显示虚拟组织
        if (StringUtils.isBlank(fisvitual)) {
            fisvitual = "0";
        }

        String whereSql = " where 1 = 1 ";
        if (DBType.isOracle()) {
            whereSql += " and ((t.fdatebegin <=  to_date('" + date + "','yyyy-MM-DD') and t.fdateend >= to_date('" + date + "','yyyy-MM-DD')) or (t.fdatebegin <= to_date('" + date + "','yyyy-MM-DD') and t.fdateend is null )) ";
        } else {
            whereSql += " and ((t.fdatebegin <= '" + date + "' and t.fdateend >= '" + date + "') or (t.fdatebegin <= '" + date + "' and t.fdateend is null )) ";
        }
        whereSql += " and t.fclass = " + fclass + " ";

        if ("0".equals(fisvitual)) {
            whereSql += " and t.fisvitual = 0 ";
        } else {
            whereSql += " and t.fisvitual in (0, 1) ";
        }
        return whereSql;
    }

    @Override
    public Map<String, Object> getUserData(Map<String, Object> request2Map, User user) {
        Map<String, Object> result = new HashMap<>();
       boolean hasRight = HasRightUtil.hasRight(user, USER_RIGHT, true);
        result.put("hasRight", hasRight);
        if (!hasRight) {
            return result;
        }
        String root = (String) request2Map.get("root");  // 根节点
        String level = (String) request2Map.get("level"); // 显示层级
        if (StringUtils.isBlank(level)) {
            level = "3";
        }

        String whereSql = userWhereSql(request2Map);

        String whereItemSql = " ";
        if ("0".equals(root)) { // 集团的情况
            whereItemSql += " and t.ftype = 0 ";
        } else {
            whereItemSql += " and t.id = '" + root + "' ";
        }

        // 获取根节点
        RecordSet rs = new RecordSet();
        rs.executeQuery("select t.id, t.fname, t.ftype, t.fparentid, t.fleadername,t.fobjid,t.fecid, t.fleaderimg, t.fleaderjob, t.fplan, t.fonjob, t.fnumber, t.fleader from jcl_org_map t " + whereSql + whereItemSql);
        List<Map<String, Object>> list = new ArrayList<>();
        String id = null;
        if (rs.next()) {
            Map<String, Object> item = new HashMap<>();
            id = rs.getString("id");
            item.put("id", rs.getString("id"));
            item.put("fname", rs.getString("fname"));
            item.put("ftype", rs.getString("ftype"));
            item.put("parentId", null);
            item.put("fleadername", rs.getString("fleadername"));
            item.put("fleaderimg", rs.getString("fleaderimg"));
            item.put("fleaderjob", rs.getString("fleaderjob"));
            item.put("fplan", rs.getString("fplan"));
            item.put("fonjob", rs.getString("fonjob"));
            item.put("hasChildren", hasChildren(rs.getString("id"), false));
            item.put("expand", "1");
            item.put("fnumber", rs.getString("fnumber"));
            item.put("fleader", rs.getString("fleader"));
            item.put("fobjid",rs.getString("fobjid"));
            list.add(item);
        }

        int currentLevel = 1;
        if (currentLevel + 1 <= Integer.parseInt(level)) {
            findUserItemByParantId(id, currentLevel + 1, level, rs, list, whereSql, true);
        }

        result.put("api_status", true);
        result.put("data", list);
        return result;
    }

    @Override
    public Map<String, Object> asyncUserData(Map<String, Object> request2Map, User user) {
        String ids = (String) request2Map.get("ids");
        String whereSql = userWhereSql(request2Map);

        whereSql += " and fparentid in (" + ids + ") ";

        RecordSet rs = new RecordSet();
        rs.executeQuery("select t.id, t.fname, t.ftype, t.fparentid, t.fleadername, t.fleaderimg, t.fleaderjob, t.fplan, t.fonjob, t.fnumber, t.fleader from jcl_org_map t " + whereSql);
        List<Map<String, Object>> currentList = new ArrayList<>();
        while (rs.next()) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", rs.getString("id"));
            item.put("fname", rs.getString("fname"));
            item.put("ftype", rs.getString("ftype"));
            item.put("parentId", rs.getString("fparentid"));
            item.put("fleadername", rs.getString("fleadername"));
            item.put("fleaderimg", rs.getString("fleaderimg"));
            item.put("fleaderjob", rs.getString("fleaderjob"));
            item.put("fplan", rs.getString("fplan"));
            item.put("fonjob", rs.getString("fonjob"));
            item.put("fnumber", rs.getString("fnumber"));
            item.put("hasChildren", hasChildren(rs.getString("id"), false));
            item.put("fleader", rs.getString("fleader"));
            currentList.add(item);
        }

        for (Map<String, Object> stringObjectMap : currentList) {
            if ("4".equals(stringObjectMap.get("ftype"))) { // 员工信息
                rs.executeQuery("select id, mobile, homeaddress from hrmresource where id = ? ", stringObjectMap.get("fnumber"));
                if (rs.next()) {
                    stringObjectMap.put("mobile", rs.getString("mobile"));
                    stringObjectMap.put("address", rs.getString("homeaddress"));
                }
                rs.executeQuery("select departmentname from hrmresource hrm \n" +
                        "left join hrmdepartment d\n" +
                        "on hrm.departmentid = d.id\n" +
                        "where hrm.id = ? ", stringObjectMap.get("fnumber"));
                if (rs.next()) {
                    stringObjectMap.put("department", rs.getString("departmentname"));
                }

            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("api_status", true);
        result.put("data", currentList);
        return result;
    }

    @Override
    public Map<String, Object> asyncCompanyData(Map<String, Object> request2Map, User user) {
        String ids = (String) request2Map.get("ids");
        String whereSql = companyDateWhereSql(request2Map);

        whereSql += " and fparentid in (" + ids + ") ";

        RecordSet rs = new RecordSet();
        rs.executeQuery("select id, fname, ftype, fparentid, fnumber from jcl_org_map " + whereSql);
        List<Map<String, Object>> currentList = new ArrayList<>();
        while (rs.next()) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", rs.getString("id"));
            item.put("fname", rs.getString("fname"));
            item.put("ftype", rs.getString("ftype"));
            item.put("parentId", rs.getString("fparentid"));
            item.put("fnumber", rs.getString("fnumber"));
            item.put("hasChildren", hasChildren(rs.getString("id"), true));
            currentList.add(item);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("api_status", true);
        result.put("data", currentList);
        return result;
    }


    private void findUserItemByParantId(String id, int currentLevel, String level, RecordSet rs, List<Map<String, Object>> list, String whereSql, boolean expand) {
        rs.executeQuery("select t.id, t.fname, t.ftype, t.fparentid, t.fleadername, t.fleaderimg, t.fleaderjob, t.fplan, t.fonjob, t.fnumber,t.fobjid,fecid from jcl_org_map t " + whereSql + " and t.fparentid = " + id);
        List<Map<String, Object>> currentList = new ArrayList<>();
        while (rs.next()) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", rs.getString("id"));
            item.put("fname", rs.getString("fname"));
            item.put("ftype", rs.getString("ftype"));
            item.put("parentId", rs.getString("fparentid"));
            item.put("fleadername", rs.getString("fleadername"));
            item.put("fleaderimg", rs.getString("fleaderimg"));
            item.put("fleaderjob", rs.getString("fleaderjob"));
            item.put("fplan", rs.getString("fplan"));
            item.put("fonjob", rs.getString("fonjob"));
            item.put("fnumber", rs.getString("fnumber"));
            item.put("expand", expand ? "1" : "0");
            item.put("fobjid", rs.getString("fobjid"));
            item.put("fecid", rs.getString("fecid"));
            item.put("hasChildren", hasChildren(rs.getString("id"), false));
            currentList.add(item);
        }

        for (Map<String, Object> stringObjectMap : currentList) {
            if ("4".equals(stringObjectMap.get("ftype"))) { // 员工信息
                rs.executeQuery("select id, mobile, homeaddress from hrmresource where id = ? ", stringObjectMap.get("fnumber"));
                if (rs.next()) {
                    stringObjectMap.put("mobile", rs.getString("mobile"));
                    stringObjectMap.put("address", rs.getString("homeaddress"));
                }
                rs.executeQuery("select departmentname from hrmresource hrm \n" +
                        "left join hrmdepartment d\n" +
                        "on hrm.departmentid = d.id\n" +
                        "where hrm.id = ? ", stringObjectMap.get("fnumber"));
                if (rs.next()) {
                    stringObjectMap.put("department", rs.getString("departmentname"));
                }

            }
            if (currentLevel + 1 <= Integer.parseInt(level)) {
                findUserItemByParantId((String) stringObjectMap.get("id"), currentLevel + 1, level, rs, list, whereSql, true);
            } else if (currentLevel == Integer.parseInt(level)) { // 多查一层
                findUserItemByParantId((String) stringObjectMap.get("id"), currentLevel + 1, level, rs, list, whereSql, false);
            }
        }
        list.addAll(currentList);
    }

    private boolean hasChildren(String id, boolean isCompany) {
        String whereSql = " where fparentid = " + id + " ";
        if (isCompany) {
            whereSql += " and ftype in (0, 1, 2) ";
        }
        grs.executeQuery("select count(1) as count from jcl_org_map " + whereSql);
        String count = "0";
        if (grs.next()) {
            count = grs.getString("count");
        }
        return !"0".equals(count);
    }
}
