package com.kingdee.eas.custom.beisen.synchronousorg;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kingdee.bos.metadata.data.SortType;
import com.kingdee.bos.metadata.entity.*;
import com.kingdee.bos.metadata.query.util.CompareType;
import com.kingdee.bos.util.BOSUuid;
import com.kingdee.eas.basedata.org.*;
import com.kingdee.eas.basedata.person.PersonInfo;
import com.kingdee.eas.custom.beisen.utils.BeiSenUtils;
import com.kingdee.eas.fi.arap.util.DBUtil;
import com.kingdee.eas.hr.base.EmpPostExperienceHis;
import com.kingdee.eas.hr.base.EmpPostExperienceHisCollection;
import com.kingdee.eas.hr.base.EmpPostExperienceHisFactory;
import com.kingdee.eas.hr.base.EmpPostExperienceHisInfo;
import com.kingdee.eas.hr.emp.PersonPositionCollection;
import com.kingdee.eas.hr.emp.PersonPositionFactory;
import com.kingdee.eas.hr.emp.PersonPositionInfo;
import com.kingdee.jdbc.rowset.IRowSet;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.net.URISyntaxException;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import com.kingdee.bos.*;


/**
 * 同步组织信息的控制类，继承自 AbstractsynchronousOrgControllerBean。
 * 主要负责创建或更新组织信息，并将其同步到外部系统。
 */
public class synchronousOrgControllerBean extends AbstractsynchronousOrgControllerBean {
    // 日志记录器，用于记录系统运行过程中的信息和错误
    private static final Logger logger = Logger.getLogger(synchronousOrgControllerBean.class);
    // 日期格式化对象，用于将日期格式化为指定的格式
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

    /**
     * 创建或更新组织信息并同步到外部系统的方法。
     *
     * @param ctx      上下文对象，包含系统运行时的环境信息
     * @param day      时间范围，用于筛选指定天数内更新的组织信息
     * @param orgId    组织 ID，如果不为空，则仅处理指定 ID 的组织信息
     * @param isDelete 是否为删除操作
     * @throws BOSException 执行过程中发生业务异常时抛出
     */
    @Override
    protected String _createOrUpdateOrg(Context ctx, int day, String orgId, boolean isDelete) throws BOSException {
        // 创建 BeiSenUtils 实例，用于与外部系统进行交互
        BeiSenUtils beiSenUtils = new BeiSenUtils(ctx);
        // 获取当前日期
        Date now = new Date();
        // 获取指定天数前的日期
        Date dayBefore = getDayBefore(now, day);
        // 创建查询视图信息，用于筛选组织信息
        EntityViewInfo entityViewInfo = createEntityViewInfo(orgId, dayBefore, now);
        String ids = "";
        try {
            // 获取组织信息本地实例
            IAdminOrgUnit localInstance = AdminOrgUnitFactory.getLocalInstance(ctx);
            // 根据查询条件获取组织信息集合
            AdminOrgUnitCollection adminOrgUnitCollection = localInstance.getAdminOrgUnitCollection(entityViewInfo);
            // 遍历组织信息集合
            for (int i = 0; i < adminOrgUnitCollection.size(); i++) {
                // 获取当前组织信息
                AdminOrgUnitInfo adminOrgUnitInfo = adminOrgUnitCollection.get(i);
                String originalId = adminOrgUnitInfo.getReserveFieldFirst();
                System.out.println("===========originalId" + originalId);
                try {
                    JSONObject requestBody = getRequestBody(ctx, adminOrgUnitInfo, null);

                    JSONObject orUpdateByOrg = beiSenUtils.createOrUpdateByOrg(requestBody, adminOrgUnitInfo);

                    System.out.println("orUpdateByOrg：" + orUpdateByOrg);
                    // 获取响应状态码
                    String code = orUpdateByOrg.getString("code");
                    if ("200".equals(code)) {
                        if (originalId == null) {
                            // 响应状态码为 200 时，更新组织信息的 originalId 字段
                            String data = orUpdateByOrg.getString("data");
                            //adminOrgUnitInfo.put("originalId", data);
                            // 保存更新后的组织信息
                            String id = adminOrgUnitInfo.getId().toString();
                            if (data != null && !data.equals("")) {
                                String sql = "update T_ORG_Admin set FreserveFieldFirst = '" + data + "' where FID = '" + id + "'";
                                DBUtil.execute(ctx, sql);
                            }
                        }
                        ids += adminOrgUnitInfo.getId().toString();
                    } else {
                        // 响应状态码不为 200 时，记录错误信息
                        logError(adminOrgUnitInfo.getName(), orUpdateByOrg.getString("message"));
                    }
                } catch (IOException e) {
                    // 捕获异常并记录错误信息
                    e.printStackTrace();
                    logError(adminOrgUnitInfo.getName(), e.getMessage());
                    logger.error("处理组织信息时发生异常", e);
                } catch (URISyntaxException e) {
                    e.printStackTrace();
                    logError(adminOrgUnitInfo.getName(), e.getMessage());
                    logger.error("处理组织信息时发生异常", e);
                }
            }
        } catch (BOSException e) {
            logger.error("获取组织信息集合时发生异常", e);
            throw e;
        }
        return ids;
        // 调用父类的 _createOrUpdateOrg 方法
//        super._createOrUpdateOrg(ctx, day, orgId, isDelete);
    }

    /**
     * 获取请求体的方法，用于构建发送到外部系统的请求信息。
     *
     * @param context          上下文对象，包含系统运行时的环境信息
     * @param adminOrgUnitInfo 组织信息对象
     * @param requestBody      请求体对象，如果为空则创建一个新的请求体
     * @return 构建好的请求体对象
     * @throws BOSException 执行过程中发生业务异常时抛出
     */
    public JSONObject getRequestBody(Context context, AdminOrgUnitInfo adminOrgUnitInfo, JSONObject requestBody) throws BOSException {
        if (requestBody == null) {
            // 请求体为空时，创建一个新的请求体
            requestBody = new JSONObject();
        }

        // 添加组织名称
        requestBody.put("name", adminOrgUnitInfo.getName());
        // 添加组织编号
        requestBody.put("code", adminOrgUnitInfo.getNumber());

        // 获取上级组织信息
        AdminOrgUnitInfo parent = adminOrgUnitInfo.getParent();
        if (parent != null) {
            // 上级组织信息不为空时，添加上级组织原始 ID
            requestBody.put("parentOriginalId", parent.getId().toString());
        }

        // 添加组织原始 ID
        requestBody.put("originalId", adminOrgUnitInfo.getId().toString());

        // 创建一个 JSON 数组，用于存储部门负责人 ID
        JSONArray originalIds = new JSONArray();
        // 获取组织的负责人岗位信息
        PositionInfo responPosition = adminOrgUnitInfo.getResponPosition();
        if (responPosition != null) {
            // 负责人岗位信息不为空时，获取人员岗位信息
            BOSUuid id = responPosition.getId();
            EntityViewInfo entityViewInfo = createPersonPositionViewInfo(id);
            try {
                EmpPostExperienceHisCollection empPostExperienceHisCollection =
                        EmpPostExperienceHisFactory.getLocalInstance(context).getEmpPostExperienceHisCollection(entityViewInfo);
//                PersonPositionCollection personPositionCollection = PersonPositionFactory
//                        .getLocalInstance(context).getPersonPositionCollection(entityViewInfo);
                // 遍历人员岗位信息集合
                for (int i = 0; i < empPostExperienceHisCollection.size(); i++) {
                    // 获取当前人员岗位信息
                    EmpPostExperienceHisInfo empPostExperienceHisInfo = empPostExperienceHisCollection.get(i);
                    // 获取人员信息
                    PersonInfo person = empPostExperienceHisInfo.getPerson();
                    // 将人员 ID 添加到部门负责人 ID 数组中
                    originalIds.add(person.getId().toString());
                }
            } catch (BOSException e) {
                logger.error("获取人员岗位信息集合时发生异常", e);
                throw e;
            }
            JSONObject customFieldList = new JSONObject();
            //部门负责人岗位编码 注释的是测试的  后面是生产的（extbumenfuzerengangweibianma_611852_1958016168，extbumenfuzerengangweimingcheng_611852_315949968）
            //customFieldList.put("extbumenfuzerengangweibianma_433107_1704083012", responPosition.getNumber());
            //customFieldList.put("extbumenfuzerengangweimingcheng_433107_501692677", responPosition.getName());
            customFieldList.put("extbumenfuzerengangweibianma_611852_1958016168", responPosition.getNumber());
            customFieldList.put("extbumenfuzerengangweimingcheng_611852_315949968", responPosition.getName());
            requestBody.put("customFieldList", customFieldList);
        }


        // 部门负责人 ID 数组不为空时，添加部门负责人 ID 数组到请求体
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("originalIds", originalIds);
        jsonObject.put("leaderType", 1);
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(jsonObject);
        requestBody.put("departmentLeaders", jsonArray);


        // 添加组织修改时间
        requestBody.put("modifiedTime", formatDate(adminOrgUnitInfo.getLastUpdateTime()));
        // 添加组织创建时间
        requestBody.put("createTime", formatDate(adminOrgUnitInfo.getCreateTime()));


//        // 获取组织是否为织状态
//        boolean isSaleOrgUnit = adminOrgUnitInfo.isIsSealUp();
//        // 根据销售组织状态设置组织状态
//        requestBody.put("status", isSaleOrgUnit ? 0 : 1);

        return requestBody;
    }

    /**
     * 获取指定日期前 x 天的日期的方法。
     *
     * @param specifiedDay 指定日期
     * @param x            天数
     * @return 指定日期前 x 天的日期
     */
    public Date getDayBefore(Date specifiedDay, int x) {
        // 获取 Calendar 实例
        Calendar c = Calendar.getInstance();
        // 设置 Calendar 的时间为指定日期
        c.setTime(specifiedDay);
        // 将日期向前移动 x 天
        c.add(Calendar.DATE, -x);
        // 返回移动后的日期
        return c.getTime();
    }

    /**
     * 创建查询视图信息的方法，用于筛选组织信息。
     *
     * @param orgId     组织 ID，如果不为空，则仅查询指定 ID 的组织信息
     * @param dayBefore 指定日期前的日期，用于筛选更新时间在该日期之后的组织信息
     * @param date      当前日期，用于筛选更新时间在该日期之前的组织信息
     * @return 查询视图信息对象
     */
    private EntityViewInfo createEntityViewInfo(String orgId, Date dayBefore, Date date) {
        // 创建查询视图信息对象
        EntityViewInfo entityViewInfo = new EntityViewInfo();
        FilterInfo filterInfo = new FilterInfo();
        if (orgId != null && !orgId.isEmpty()) {
            // orgId 不为空时，添加查询条件，筛选组织 ID 等于指定 ID 的组织信息
            filterInfo.getFilterItems().add(new FilterItemInfo("id", orgId, CompareType.EQUALS));
        } else {
            // orgId 为空时，添加查询条件，筛选更新时间在指定日期范围之内的组织信息
            filterInfo.getFilterItems().add(new FilterItemInfo("lastUpdateTime", dayBefore, CompareType.GREATER_EQUALS));
            filterInfo.getFilterItems().add(new FilterItemInfo("lastUpdateTime", date, CompareType.LESS_EQUALS));
            filterInfo.getFilterItems().add(new FilterItemInfo("isSealUp",false,CompareType.EQUALS));
        }
        // 设置查询条件到查询视图信息对象中
        entityViewInfo.setFilter(filterInfo);

        // 创建排序项集合
        SorterItemCollection sorterItemCollection = new SorterItemCollection();
        SorterItemInfo sorterItemInfo = new SorterItemInfo();
        // 设置排序字段为组织长编号
        sorterItemInfo.setPropertyName("longNumber");
        // 设置排序方式为升序
        sorterItemInfo.setSortType(SortType.ASCEND);
        sorterItemCollection.add(sorterItemInfo);
        // 设置排序项集合到查询视图信息对象中
        entityViewInfo.setSorter(sorterItemCollection);

        // 创建选择项集合
        SelectorItemCollection selectorItemCollection = new SelectorItemCollection();
        selectorItemCollection.add("*");
        selectorItemCollection.add("parent.*");
        selectorItemCollection.add("responPosition.*");
        // 设置选择项集合到查询视图信息对象中
        entityViewInfo.setSelector(selectorItemCollection);

        return entityViewInfo;
    }


    /**
     * 创建人员岗位查询视图信息的方法，用于筛选人员岗位信息。
     *
     * @param positionId 岗位 ID
     * @return 人员岗位查询视图信息对象
     */
    private EntityViewInfo createPersonPositionViewInfo(BOSUuid positionId) {
        // 创建查询视图信息对象
        EntityViewInfo entityViewInfo = new EntityViewInfo();
        FilterInfo filterInfo = new FilterInfo();
        // 添加查询条件，筛选主要岗位等于指定岗位 ID 的人员岗位信息
        filterInfo.getFilterItems().add(new FilterItemInfo("Position", positionId.toString(), CompareType.EQUALS));
        // 添加查询条件，筛选人员已同步的人员岗位信息
        filterInfo.getFilterItems().add(new FilterItemInfo("person.bsUserId is not null"));
        filterInfo.getFilterItems().add(new FilterItemInfo("Leffdt", new Date(), CompareType.GREATER_EQUALS));
        Set<String> stringSet = new HashSet<String>();
        stringSet.add("1");
        stringSet.add("4");
        filterInfo.getFilterItems().add(new FilterItemInfo("person.employeeType.inService", stringSet, CompareType.INCLUDE));
        // 设置查询条件到查询视图信息对象中
        entityViewInfo.setFilter(filterInfo);

        SelectorItemCollection selectorItemCollection = new SelectorItemCollection();
        selectorItemCollection.add("*");
        selectorItemCollection.add("person.*");
        // 设置选择项集合到查询视图信息对象中
        entityViewInfo.setSelector(selectorItemCollection);
        System.out.println("=============entityViewInfo" + entityViewInfo);
        return entityViewInfo;
    }

    /**
     * 格式化日期的方法，将日期格式化为指定格式。
     *
     * @param date 要格式化的日期
     * @return 格式化后的日期字符串
     */
    private String formatDate(Date date) {
        if (date == null) {
            return null;
        }
        return DATE_FORMAT.format(date);
    }

    /**
     * 记录错误信息的方法，将错误信息输出到控制台并记录到日志文件中。
     *
     * @param orgName 组织名称
     * @param message 错误信息
     */
    private void logError(String orgName, String message) {
        String errorMsg = orgName + " 同步失败：" + message;
        System.out.println(errorMsg);
        logger.error(errorMsg);
    }
}