package nckd.jxccl.base.org.helper;

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.basedata.BaseDataServiceHelper;
import kd.hr.hbp.business.servicehelper.HRBaseServiceHelper;
import nckd.jxccl.base.common.utils.ConvertUtil;
import nckd.jxccl.base.entity.helper.EntityHelper;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Org帮助类
 *
 * @author W.Y.C
 * @version 1.0
 * @date 2025/12/4 10:22
 */
public class OrgHelper {

    static QFilter isNotCurrent = new QFilter("iscurrentversion", "=", '0');
    static QFilter isCurrent = new QFilter("iscurrentversion", "=", "1");
    static QFilter dataStatusFilter = new QFilter("datastatus", "in", Arrays.asList("1", "2"));
    static QFilter dataStatusCurrent = new QFilter("datastatus", "in", Arrays.asList("-3", "0"));
    static QFilter enableFilter = new QFilter("enable", "=", "1");
    static QFilter initStatusFilter = new QFilter("initstatus", "=", "2");

    /**
     * 获取创建组织
     * @param entity 实体id
     * @return: java.lang.Long
     * @author W.Y.C
     * @date: 2025/12/04 10:27
     */
    public static Long getCreateOrgList(String entity) {
        List<Long> createOrgList = BaseDataServiceHelper.getCreateOrgList(entity);
        if (createOrgList != null && !createOrgList.isEmpty()) {
            return createOrgList.get(0);
        }
        return null;
    }

    /**
     * 获取创建组织
     * @param entity 实体id
     * @return: java.lang.Long
     * @author W.Y.C
     * @date: 2025/12/04 10:27
     */
    public static DynamicObject getCreateOrg(String entity) {
        List<Long> createOrgList = BaseDataServiceHelper.getCreateOrgList(entity);
        if (createOrgList != null && !createOrgList.isEmpty()) {
            return EntityHelper.newEntity(entity,createOrgList.get(0));

        }
        return null;
    }

    /**
     * 获取控制策略
     * @param entity 实体id
     * @param createOrg 创建组织id
     * @return: java.lang.String
     * @author W.Y.C
     * @date: 2025/12/04 10:26
     */
    public static String getBdCtrlStrgy(String entity, Long createOrg) {
        return BaseDataServiceHelper.getBdCtrlStrgy(entity, ConvertUtil.toStr(createOrg));
    }


    /**
     * 获取组织结构编码Map
     * key = structnumber， value = Map包含number和name
     * @param structNumberSet
     * @param modifyTime
     * @return
     */
    public static Map<String, Map<String, String>> getStructNumberMap(Set<String> structNumberSet, Date modifyTime) {
        HRBaseServiceHelper adminOrg = new HRBaseServiceHelper("haos_adminorgdetail");
        QFilter structNumberFilter = new QFilter("structnumber", "in", structNumberSet);
        if (Objects.isNull(modifyTime)) {
            structNumberFilter.and(isCurrent);
        } else {
            QFilter effDateFilter = (new QFilter("bsed", "<=", modifyTime)).and(new QFilter("bsled", ">=", modifyTime));
            structNumberFilter.and(isNotCurrent).and(effDateFilter);
        }

        DynamicObject[] adminOrgNumber = adminOrg.query("id,structnumber,name,number", new QFilter[]{structNumberFilter, dataStatusFilter});
        Stream<DynamicObject> dynamicObjectStream = Arrays.stream(adminOrgNumber).filter(distinctByKey1((s) -> {
            return s.getString("structnumber");
        }));
        Map<String, Map<String, String>> stringStringMap = (Map)dynamicObjectStream.collect(Collectors.toMap((dy) -> {
            return (String)Optional.ofNullable(dy.getString("structnumber")).orElse("");
        }, (dy) -> {
            Map map = new HashMap<>();
            map.put("number",(String)Optional.ofNullable(dy.getString("number")).orElse(""));
            map.put("name",(String)Optional.ofNullable(dy.getString("name")).orElse(""));
            return map;
        }));
        structNumberSet.removeAll(stringStringMap.keySet());
        if (structNumberSet.size() == 0) {
            return stringStringMap;
        } else {
            structNumberFilter = new QFilter("structnumber", "in", structNumberSet);
            DynamicObject[] adminOrgNumberNot = adminOrg.query("id,structnumber,name,number", new QFilter[]{structNumberFilter, isCurrent, dataStatusCurrent, enableFilter});
            dynamicObjectStream = Arrays.stream(adminOrgNumberNot).filter(distinctByKey1((s) -> {
                return s.getString("structnumber");
            }));
            Map<String, Map<String, String>> stringStringMapNot = (Map)dynamicObjectStream.collect(Collectors.toMap((dy) -> {
                return (String)Optional.ofNullable(dy.getString("structnumber")).orElse("");
            }, (dy) -> {
                Map map = new HashMap<>();
                map.put("number",(String)Optional.ofNullable(dy.getString("number")).orElse(""));
                map.put("name",(String)Optional.ofNullable(dy.getString("name")).orElse(""));
                return map;
            }));
            stringStringMap.putAll(stringStringMapNot);
            return stringStringMap;
        }
    }


    /**
     * 根据组织的structlongnumber处理组织的长名称
     * @param org
     * @param structMap
     */
    public static void dealLongName(DynamicObject org, Map<String, Map<String, String>> structMap) {
        String structLongNumber = org.getString("structlongnumber");
        String[] structNumbers =  structLongNumber.split("!");
        String[] longNames = new String[structNumbers.length];
        String[] longNumbers = new String[structNumbers.length];
        for(int i = 0; i<structNumbers.length; i++) {
            if(structMap.containsKey(structNumbers[i])) {
                longNames[i] = structMap.get(structNumbers[i]).get("name");
                longNumbers[i] = structMap.get(structNumbers[i]).get("number");
            }
        }
        org.set("nckd_orglongname", String.join("_", longNames));
    }


    static <T> Predicate<T> distinctByKey1(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap();
        return (t) -> {
            return seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
        };
    }




}
