package com.kingdee.eas.custom.beisen.synchronouspos.osf;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.bsf.service.app.IHRMsfService;
import com.kingdee.bos.rabbitmq.guava.Lists;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.beisen.utils.BeiSenUtils;
import com.kingdee.eas.custom.beisen.utils.BeisenParamByPropertiesUtil;
import com.kingdee.eas.custom.beisen.utils.Helper;
import com.kingdee.eas.util.ExceptionUtil;
import com.kingdee.eas.util.app.DbUtil;
import com.kingdee.jdbc.rowset.IRowSet;
import com.kingdee.shr.base.syssetting.IMSFServiceFacade;
import com.kingdee.shr.base.syssetting.MSFServiceFacadeFactory;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 编制同步
 * description: SynchronousPosOSFService <br>
 * date: 2025/7/11 17:46 <br>
 * author: lhbj <br>
 * version: 1.0 <br>
 */
public class SyncStaffManageOSFService implements IHRMsfService {


    public Map<String, List<Map<String, Object>>> orgProcess(Context context, List<Map<String, Object>> orgListMap) throws IOException, URISyntaxException {
        return new StaffManageProcess().orgProcess(context, orgListMap);
    }

    public Map<String, List<Map<String, Object>>> posProcess(Context context, List<Map<String, Object>> posListMap) throws IOException, URISyntaxException {
        return new StaffManageProcess().posProcess(context, posListMap);
    }

    @Override
    public Object process(Context context, Map<String, Object> map) throws EASBizException, BOSException {
        String mack = (String) map.get("mack");

        Map<String, Object> result = Maps.newHashMap();
        List<Map<String, Object>> list = Lists.newArrayList();
        List<Map<String, Object>> listMap = Lists.newArrayList();
        List<Map<String, Object>> orgListMap = Lists.newArrayList();
        List<Map<String, Object>> posListMap = Lists.newArrayList();
        result.put("list", list);
        result.put("listMap", listMap);
        String posPath = (String) map.get("posPath");
        String orgPath = (String) map.get("orgPath");
        StringBuilder sql = new StringBuilder();
        sql.append(" ");
        sql.append(" select fid,FYear,FTableName from T_HR_StaffManageProject ");
        sql.append(" where FRule in ( ");
        sql.append("         select fid from T_HR_StaffManageRule where fid in ( ");
        sql.append("                 select FStaffManageRuleId from T_HR_STAFFMANAGERULEFIELD where FColumn in ('FpositionID', 'FAdminOrgID') group by FStaffManageRuleId HAVING count(fid)>1 ");
        sql.append("         ) and FState = 1 ");
        sql.append(" ) ");
        sql.append(" and FState = 1 ");
        sql.append(" and FChannel = 1 ");
        IRowSet rs = DbUtil.executeQuery(context, sql.toString());
        try {
            BeisenParamByPropertiesUtil posUtil = new BeisenParamByPropertiesUtil(posPath);
            Map<String, String> poskeyMap = posUtil.getConfig();
            BeisenParamByPropertiesUtil orgUtil = new BeisenParamByPropertiesUtil(orgPath);
            Map<String, String> orgkeyMap = orgUtil.getConfig();
            while (rs.next()) {
                String fid = rs.getString("fid");
                String FTableName = rs.getString("FTableName");
                String FYear = rs.getString("FYear");
                StringBuilder selSql = new StringBuilder();
                selSql.append(" select * from ( ");
                selSql.append(" select 'org' orgpos,org.fid posId,org.Fnumber orgOriginalId,org.FParentID,org.fname_l2 orgPosName,org.FDisplayName_L2 staffName, ");
                //selSql.append("         org.Fid CFOriginalId, ");
                selSql.append("         org.Fnumber CFOriginalId, ");
                //selSql.append("         (case when staff.FControlWay=0 then 3 when staff.FControlWay=1 then 2 else 1 end) FControlWay, ");
                selSql.append("         staff.FControlWay FControlWay, ");
                selSql.append("         staff.FPersonCount,staff.FStaffYear,staff.FYearActualStart, ");
                selSql.append("         staff.FOnWayAddCount,staff.FOnWaySubCount, ");
                selSql.append("         (staff.FStaffYear-staff.FOnWayAddCount+staff.FOnWaySubCount-staff.FPersonCount) FStaffYearUsable, ");
                selSql.append("         (staff.FState) FState,staff.FContainSub, ");
                selSql.append(" 1 orgPosStatus ");
                selSql.append(" from ");
                selSql.append(" " + FTableName + " staff ");
                selSql.append(" left join t_org_admin org on org.fid=staff.FAdminOrgID ");
                selSql.append(" left join t_org_position pos on pos.fid = staff.FpositionID ");
                selSql.append(" where pos.fid is null and org.FReserveFieldFirst is not null ");
                selSql.append(" UNION all ");
                selSql.append(" select 'pos' orgpos,pos.fid posId,org.FreserveFieldFirst orgOriginalId,pos.FParentID,pos.fname_l2 orgPosName,org.FDisplayName_L2 staffName,pos.CFOriginalId, ");
                //selSql.append(" (case when staff.FControlWay=0 then 3 when staff.FControlWay=1 then 2 else 1 end) FControlWay, ");
                selSql.append("         staff.FControlWay FControlWay, ");
                selSql.append("         staff.FPersonCount,staff.FStaffYear,staff.FYearActualStart, ");
                selSql.append("         staff.FOnWayAddCount,staff.FOnWaySubCount, ");
                selSql.append("         (staff.FStaffYear-staff.FOnWayAddCount+staff.FOnWaySubCount-staff.FPersonCount) FStaffYearUsable, ");
                selSql.append("         (staff.FState) FState,staff.FContainSub, ");
                selSql.append("  (case when pos.FDELETEDSTATUS=2 then 0 else 1 end) orgPosStatus ");
                selSql.append(" from ");
                selSql.append(" " + FTableName + " staff ");
                selSql.append(" left join t_org_position pos on pos.fid = staff.FpositionID ");
                selSql.append(" left join t_org_admin org on org.fid=pos.FADMINORGUNITID ");
                selSql.append(" where pos.fid is not null and pos.CFOriginalId is not null ");
                selSql.append(" ) t order by t.FContainSub desc ");
                IRowSet rsSel = DbUtil.executeQuery(context, selSql.toString());
                // 获取访问令牌

                while (rsSel.next()) {
                    String orgpos = rsSel.getString("orgpos");
                    if ("org".equals(orgpos)) {
                        Map<String, Object> pos = this.getPostData(orgkeyMap, rsSel);
                        if (null != pos) {
                            orgListMap.add(pos);
                        }
                    } else if ("pos".equals(orgpos)) {
                        Map<String, Object> pos = this.getPostData(poskeyMap, rsSel);
                        if (null != pos) {
                            posListMap.add(pos);
                        }
                    }
                }
                result.put("orgListMap", orgListMap);
                result.put("posListMap", posListMap);

            }
            if ("org".equals(mack) || "pos".equals(mack)) {
                //Map<String,List<Map<String,Object>>> resultOrg = this.orgProcess(context,orgListMap);
            } else {
                ExecutorService executor = Executors.newFixedThreadPool(4);
                int orgLen = orgListMap.size();
                int batchSize = 50;
                for (int i = 0; i < orgLen; i += batchSize) {
                    int end = Math.min(i + batchSize, orgLen);
                    List<Map<String, Object>> orgSubListMap = orgListMap.subList(i, end);
                    SyncOrgStaffManageRunnable syncOrg = new SyncOrgStaffManageRunnable(context, orgSubListMap);
                    executor.submit(syncOrg);
                }

                int posLen = posListMap.size();
                for (int i = 0; i < posLen; i += batchSize) {
                    int end = Math.min(i + batchSize, posLen);
                    List<Map<String, Object>> posSubListMap = posListMap.subList(i, end);
                    SyncPosStaffManageRunnable syncOrg = new SyncPosStaffManageRunnable(context, posSubListMap);
                    executor.submit(syncOrg);
                }
                executor.shutdown();
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.put("errMsg", ExceptionUtil.getExcLinkStackTrace(e));
        } finally {

        }
        return result;
    }

    /**
     * shr系统数据组装北森请求参数
     *
     * @param keyMap
     * @param rowSet
     * @return
     * @throws SQLException
     */
    protected Map<String, Object> getPostData(Map<String, String> keyMap, IRowSet rowSet) throws SQLException {
        Map<String, Object> pos = Maps.newHashMap();
        if (null != rowSet) {
            for (Map.Entry<String, String> entry : keyMap.entrySet()) {
                String shrKey = entry.getKey();
                String beisenKey = entry.getValue();
                if (shrKey.indexOf(".") > 0) {
                    String[] keys = shrKey.split("\\.");
                    if (2 == keys.length) {
                        Map<String, Object> map1 = (Map<String, Object>) pos.get(keys[0]);
                        if (null == map1) {
                            map1 = Maps.newHashMap();
                            pos.put(keys[0], map1);
                        }
                        String valueStr = rowSet.getString(keys[1]);
                        if (beisenKey.indexOf(",") > 0) {
                            String[] beisenKeys = beisenKey.split(",");
                            Object value = null;

                            if ("integer".equals(beisenKeys[1])) {
                                if (null != valueStr) {
                                    value = Integer.parseInt(valueStr);
                                }
                            } else {
                                value = valueStr;
                            }
                            if (null != value) {
                                map1.put(beisenKeys[0], value);
                            }
                        } else {

                            if (null != valueStr) {
                                map1.put(beisenKey, valueStr);
                            }
                        }
                    } else if (3 == keys.length) {
                        Map<String, Object> map1 = (Map<String, Object>) pos.get(keys[0]);
                        if (null == map1) {
                            map1 = Maps.newHashMap();
                            pos.put(keys[0], map1);
                        }
                        Map<String, Object> map2 = (Map<String, Object>) map1.get(keys[1]);
                        if (null == map2) {
                            map2 = Maps.newHashMap();
                            map1.put(keys[1], map1);
                        }
                        String valueStr = rowSet.getString(keys[2]);
                        if (beisenKey.indexOf(",") > 0) {
                            String[] beisenKeys = beisenKey.split(",");
                            Object value = null;

                            if ("integer".equals(beisenKeys[1])) {
                                if (null != valueStr) {
                                    value = Integer.parseInt(valueStr);
                                }
                            } else {
                                value = valueStr;
                            }
                            if (null != value) {
                                map2.put(beisenKeys[0], value);
                            }
                        } else {
                            if (null != valueStr) {
                                map2.put(beisenKey, valueStr);
                            }
                        }
                    }
                } else {
                    String valueStr = rowSet.getString(shrKey);
                    if (beisenKey.indexOf(",") > 0) {
                        String[] beisenKeys = beisenKey.split(",");
                        Object value = null;
                        if ("integer".equals(beisenKeys[1])) {
                            if (null != valueStr) {
                                value = Integer.parseInt(valueStr);
                            }
                        } else {
                            value = valueStr;
                        }
                        if (null != value) {
                            pos.put(beisenKeys[0], value);
                        }
                    } else {
                        if (null != valueStr) {
                            pos.put(beisenKey, valueStr);
                        }
                    }
                }
            }
        }
        return pos;
    }


}
