package shkd.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.bos.util.HttpClientUtils;
import kd.bos.util.StringUtils;

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

import static shkd.repc.resm.opplugin.PushOASupplierOPPlugin.RESM_OFFICIAL_SUPPLIER;
import static shkd.repc.resm.opplugin.PushOASupplierOPPlugin.assembleBody;

/**
 * @author :weiyunlong
 * @date :Created 2024/9/11 16:02
 * @description:致远OA集成工具类
 */
public class OAUtils {

    private static final Log logger = LogFactory.getLog(OAUtils.class);
//    public static final String oaUrl = "https://newoa.dobechina.com";//(正式环境外网地址)
    public static final String oaUrl = System.getProperty("oaurl");//(测试环境外网地址)http://140.206.96.138:9091
//    public static final String oaUrl = "http://172.31.254.240:9090";//本地(内网地址)


    //致远服务前获取token接口
    public static String getOaToken(String billNo){

        String userName = "JDtest";
        String password = "235c78d7-03a6-4b32-8632-7b75a002276b";
        String linkUrl = oaUrl +"/seeyon/rest/token";
        //接口请求体
        JSONObject linkBody = new JSONObject();
        linkBody.put("userName", System.getProperty("oaUserName"));
        linkBody.put("password", System.getProperty("oaPassword"));
        String token = "";

        try {
            String linkPostjson = HttpClientUtils.postjson(linkUrl, null, linkBody.toJSONString());
            logger.info("获取OaToken接口返回结果:\n{}", linkPostjson);

            if (StringUtils.isNotEmpty(linkPostjson)) {

                JSONObject jsonObject = JSONObject.parseObject(linkPostjson);
                token = jsonObject.getString("id");
                DobeDWUtils.saveLog(billNo,
                        "致远",linkBody.toJSONString(),	linkPostjson,
                        true,"调用致远服务前获取token接口");
            }
            return token;
        } catch (Exception e) {
            logger.info(String.format("获取OaToken接口异常:%s", e.getMessage()));
            DobeDWUtils.saveLog(billNo,
                    "致远",linkBody.toJSONString(),	e.getMessage(),
                    false,"调用致远服务前获取token接口");
            throw new RuntimeException(e);
        }
    }

    /**
     *  OA供应商同步接口
     */
    public static void pushOASupplier(String oaToken, DynamicObject dataEntity){
        //ICS新增/更新OA客户租户接口
        String customerUrl = OAUtils.oaUrl+"/seeyon/rest/ats/type/customer";

        Map<String, String> customerHeader = new HashMap<>();
        customerHeader.put("Content-Type", "application/json");
        customerHeader.put("token", oaToken);

        //组装请求体
//        DynamicObject supplier = dataEntity.getDynamicObject("syssupplier");//系统供应商
//        if (null != supplier) {
        JSONObject customerBody = assembleBody(OAUtils.l(dataEntity.getPkValue()));
        if (customerBody != null) {
            String customerPostjson = null;
            boolean isSuccess = false; // 新增变量来标记成功状态
            try {
                customerPostjson = HttpClientUtils.postjson(customerUrl, customerHeader, customerBody.toJSONString());
                JSONObject jsonObject = JSONObject.parseObject(customerPostjson);

                if (!jsonObject.isEmpty()) {
                    isSuccess = "true".equals(jsonObject.getString("success"));
                    if (isSuccess) {
                        String id = jsonObject.getString("id");
                        // 获取正式供应商
                        QFilter q = new QFilter("id", QCP.equals, dataEntity.getPkValue());
                        DynamicObject officialSupplier = BusinessDataServiceHelper.loadSingle(RESM_OFFICIAL_SUPPLIER, new QFilter[]{q});
                        if (officialSupplier != null) {
                            officialSupplier.set("qeug_oacode", id);
                            SaveServiceHelper.save(new DynamicObject[]{officialSupplier});
                        }
                    }
                }
            } catch (Exception ex) {
                DobeDWUtils.saveLog(dataEntity.getString("name"), "致远", customerBody.toJSONString(), customerPostjson, false, "调用ICS新增/更新OA客户租户接口");
                throw new RuntimeException(ex);
            } finally {
                // 日志记录,放在 finally 中确保无论如何都会执行
                DobeDWUtils.saveLog(dataEntity.getString("name"), "致远", customerBody.toJSONString(), customerPostjson, isSuccess, isSuccess ? "调用ICS更新OA客户租户接口" : "调用ICS新增OA客户租户接口");
            }
        }
//        }

    }

    /**
     *  OA接口绑定用户
     *  用户的绑定 金蝶通过定时任务 增量推就行,或者金蝶系统有人员进来推一次,这个人绑定成功了 就不需要再绑定,除非人员工号有变动
     * @param approversLists  金蝶系统的审批人集合
     * @param oaToken  致远OA获取的token
     */
    public static String thirdpartyUser(List<DynamicObject> approversLists, String oaToken,String billNo){

//        String oaUrl = System.getProperty("oaurl");
        String thirdUrl = oaUrl + "/seeyon/rest/thirdpartyUserMapper/binding";

        Map<String, String> customerHeader = new HashMap<>();
        customerHeader.put("Content-Type", "application/json");
        customerHeader.put("token", oaToken);

        //组装请求体
        JSONObject thirdBody = new JSONObject();
        JSONArray thirdList = new JSONArray();
        //接口不支持接收人字段为多人,但接口支持批量  so 多人审批,遍历审批人集合,调用OA调待办接口
        for (DynamicObject approver : approversLists) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("registerCode", "3004");//系统注册编码:3004
            jsonObject.put("thirdUserId",approver.getString("number"));//三方系统人员编码(通过人员编码匹配,需要和OA保持一致)
            jsonObject.put("thirdLoginName", approver.getString("name"));//三方系统人员登录名
            jsonObject.put("thirdName", approver.getString("name"));//三方系统人员姓名
            jsonObject.put("thirdCode", approver.getString("number"));//三方系统人员编码
//            jsonObject.put("thirdUserId","jdtest");
//            jsonObject.put("thirdLoginName", "金蝶测试");
//            jsonObject.put("thirdName", "金蝶测试");
//            jsonObject.put("thirdCode","jdtest");
            thirdList.add(jsonObject);
        }
        thirdBody.put("userlist", thirdList);

        String thirdPostjson = null;
        try {
            // 发送POST请求并获取响应
            thirdPostjson = HttpClientUtils.postjson(thirdUrl, customerHeader, thirdBody.toJSONString());
            JSONObject jsonObject = JSONObject.parseObject(thirdPostjson);

            // 检查JSON对象是否为空
            if (jsonObject != null && !jsonObject.isEmpty()) {
                Boolean result = jsonObject.getBoolean("success");
                String logMessage = result ? "OA接口绑定用户成功!" : "OA接口绑定用户失败!";
                logger.info(logMessage);

                // 记录日志
                DobeDWUtils.saveLog(billNo, "致远", thirdBody.toJSONString(), thirdPostjson, result, "调用致远用户绑定接口");
                // 若绑定用户失败,抛出异常
                if (!result) {
                    throw new RuntimeException("OA接口绑定用户失败" + thirdPostjson);
                }
            }
        } catch (Exception e) {
            // 记录异常信息
            String errorMessage = String.format("接口异常:%s", e.getMessage());
            logger.info(errorMessage);
            DobeDWUtils.saveLog(billNo, "致远", thirdBody.toJSONString(), e.getMessage(), false, "调用致远用户绑定接口");
            throw new RuntimeException(e);
        }
        return thirdPostjson;

    }

    /**
     * 金蝶系统推送OA待办新增
     * @param thirdPartyMap 流程参数
     */
    public static void thirdParty(HashMap<String, Object> thirdPartyMap){

//        String oaUrl = System.getProperty("oaurl");
        String pendingsUrl = oaUrl + "/seeyon/rest/thirdpartyPending/receive/pendings";

        Map<String, String> customerHeader = new HashMap<>();
        customerHeader.put("Content-Type", "application/json");
        customerHeader.put("token", String.valueOf(thirdPartyMap.get("oaToken")));
        //组装请求体
        JSONObject pendingsBody = new JSONObject();
        JSONArray pendingList = new JSONArray();
        //接口不支持接收人字段为多人,但接口支持批量  so 多人审批,遍历审批人集合,调用OA调待办接口
        List<DynamicObject> approversLists = (List<DynamicObject>)thirdPartyMap.get("approversLists");
        for (DynamicObject approver :approversLists ) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("taskId",  String.valueOf(thirdPartyMap.get("taskId")));//第三方待办主键(保证唯一)
            jsonObject.put("registerCode", "3004");//系统注册编码
            jsonObject.put("title",  String.valueOf(thirdPartyMap.get("title")) );//待办标题
            jsonObject.put("thirdSenderId", String.valueOf(thirdPartyMap.get("startNumber")));//第三方待办发起人主键
//            jsonObject.put("thirdSenderId", "jdtest");//todo 第三方待办发起人主键
            jsonObject.put("senderName",  String.valueOf(thirdPartyMap.get("startName")) );//第三方待办发起人姓名
//            jsonObject.put("senderName",  "金蝶测试" );//todo 第三方待办发起人姓名
            jsonObject.put("thirdReceiverId", approver.getString("number"));//第三方待办接收人主键(保证唯一)
//            jsonObject.put("thirdReceiverId", "jdtest");//todo 第三方待办接收人主键(保证唯一)
            jsonObject.put("creationDate",   String.valueOf(thirdPartyMap.get("createDateStr")));//待办创建时间(格式:yyyy-MM-dd HH:mm:ss)
            jsonObject.put("state", "0");//状态:0:未办理;1:已办理
            jsonObject.put("url",   String.valueOf(thirdPartyMap.get("url")));//PC端穿透链接
            jsonObject.put("h5url", String.valueOf(thirdPartyMap.get("h5url")));//移动端穿透链接
            pendingList.add(jsonObject);
        }
        pendingsBody.put("pendingList", pendingList);

        String pendingPostjson = null;
        try {
            // 发送POST请求并获取响应
            pendingPostjson = HttpClientUtils.postjson(pendingsUrl, customerHeader, pendingsBody.toJSONString());
            JSONObject jsonObject = JSONObject.parseObject(pendingPostjson);

            // 检查JSON对象是否为空
            if (jsonObject != null && !jsonObject.isEmpty()) {
                Boolean result = jsonObject.getBoolean("success");
                String logMessage = result ? "金蝶系统推送OA待办新增成功!" : "金蝶系统推送OA待办新增失败!";

                // 记录日志
                logger.info(logMessage);
                DobeDWUtils.saveLog(String.valueOf(thirdPartyMap.get("billNo")),
                        "致远", pendingsBody.toJSONString()+"\n"+String.valueOf(thirdPartyMap.get("url1")), pendingPostjson,
                        result, "调用推送OA待办新增接口");
            }

            logger.info("接口返回结果:\n{}", pendingPostjson);

        } catch (Exception e) {
            // 记录异常信息
            String errorMessage = String.format("接口异常:%s", e.getMessage());
            logger.info(errorMessage);
            DobeDWUtils.saveLog(String.valueOf(thirdPartyMap.get("billNo")),
                    "致远", pendingsBody.toJSONString(), e.getMessage(),
                    false, "调用推送OA待办新增接口");
            throw new RuntimeException(e);
        }

    }

    /**
     * OA待办变更
     * @param updateStateMap 流程参数
     */
    public static void updatePendingState (HashMap<String, Object> updateStateMap){

//        String oaUrl = System.getProperty("oaurl");
        String pendingsUrl = oaUrl + "/seeyon/rest/thirdpartyPending/updatePendingState";

        Map<String, String> customerHeader = new HashMap<>();
        customerHeader.put("Content-Type", "application/json");
        customerHeader.put("token", String.valueOf(updateStateMap.get("oaToken")));
        //组装请求体
        JSONObject pendingsBody = new JSONObject();
        pendingsBody.put("registerCode","3004");
        pendingsBody.put("taskId",String.valueOf(updateStateMap.get("taskId")));
        pendingsBody.put("state",String.valueOf(updateStateMap.get("state")));
        pendingsBody.put("subState",String.valueOf(updateStateMap.get("subState")));

        String pendingPostjson = null;
        try {
            // 发送POST请求并获取响应
            pendingPostjson = HttpClientUtils.postjson(pendingsUrl, customerHeader, pendingsBody.toJSONString());
            JSONObject jsonObject = JSONObject.parseObject(pendingPostjson);

            // 检查JSON对象是否为空
            if (jsonObject != null && !jsonObject.isEmpty()) {
                Boolean result = jsonObject.getBoolean("success");
                String logMessage = result ? "金蝶系统推送OA待办变更成功!" : "金蝶系统推送OA待办变更失败!";

                // 记录日志
                logger.info(logMessage);
                DobeDWUtils.saveLog(String.valueOf(updateStateMap.get("billNo")),
                        "致远", pendingsBody.toJSONString(), pendingPostjson,
                        result, "调用推送OA待办变更接口");
            }

            logger.info("接口返回结果:\n{}", pendingPostjson);

        } catch (Exception e) {
            // 记录异常信息
            String errorMessage = String.format("接口异常:%s", e.getMessage());
            logger.info(errorMessage);
            DobeDWUtils.saveLog(String.valueOf(updateStateMap.get("billNo")),
                    "致远", pendingsBody.toJSONString(), e.getMessage(),
                    false, "调用推送OA待办变更接口");
            throw new RuntimeException(e);
        }



    }

    /**
     * 金蝶系统推送OA消息
     * @param thirdPartyMap 流程参数
     */
    public static void thirdpartyMessage(HashMap<String, Object> thirdPartyMap){

//        String oaUrl = System.getProperty("oaurl");
        String messagesUrl = oaUrl + "/seeyon/rest/thirdpartyMessage/receive/messageList";

        Map<String, String> messageHeader = new HashMap<>();
        messageHeader.put("Content-Type", "application/json");
        messageHeader.put("token", String.valueOf(thirdPartyMap.get("oaToken")));
        //组装请求体
        JSONObject messageBody = new JSONObject();
        JSONArray messageList = new JSONArray();
        //接口不支持接收人字段为多人,但接口支持批量  so 多人审批,遍历审批人集合,调用OA调待办接口
        List<DynamicObject> approversLists = (List<DynamicObject>)thirdPartyMap.get("approversLists");
        for (DynamicObject approver :approversLists ) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("thirdpartyMessageId",  String.valueOf(thirdPartyMap.get("taskId")));//待办主键(保证唯一)
            jsonObject.put("thirdpartyRegisterCode", "3004");//系统注册编码
            jsonObject.put("messageContent",  String.valueOf(thirdPartyMap.get("content")) );//消息内容
            jsonObject.put("thirdpartySenderId", String.valueOf(thirdPartyMap.get("startNumber")));//发起人主键
//            jsonObject.put("thirdpartySenderId", "jdtest");//todo 发起人主键
            jsonObject.put("thirdpartyReceiverId", approver.getString("number"));//接收人主键(保证唯一)
//            jsonObject.put("thirdpartyReceiverId", "jdtest");//todo 接收人主键(保证唯一)
            jsonObject.put("creation_date",   String.valueOf(thirdPartyMap.get("createDateStr")));//创建时间(格式:yyyy-MM-dd HH:mm:ss)
            jsonObject.put("messageURL",   String.valueOf(thirdPartyMap.get("url")));//PC端穿透链接
            jsonObject.put("messageH5URL", String.valueOf(thirdPartyMap.get("h5url")));//移动端穿透链接
            messageList.add(jsonObject);
        }
        messageBody.put("messages", messageList);

        String pendingPostjson = null;
        try {
            // 发送POST请求并获取响应
            pendingPostjson = HttpClientUtils.postjson(messagesUrl, messageHeader, messageBody.toJSONString());
            JSONObject jsonObject = JSONObject.parseObject(pendingPostjson);

            // 检查JSON对象是否为空
            if (jsonObject != null && !jsonObject.isEmpty()) {
                Boolean result = jsonObject.getBoolean("success");
                String logMessage = result ? "金蝶系统推送OA消息成功!" : "金蝶系统推送OA消息失败!";

                // 记录日志
                logger.info(logMessage);
                DobeDWUtils.saveLog(String.valueOf(thirdPartyMap.get("billNo")),
                        "致远", messageBody.toJSONString()+"\n"+String.valueOf(thirdPartyMap.get("url1")), pendingPostjson,
                        result, "调用推送OA消息接口");
            }

            logger.info("接口返回结果:\n{}", pendingPostjson);

        } catch (Exception e) {
            // 记录异常信息
            String errorMessage = String.format("接口异常:%s", e.getMessage());
            logger.info(errorMessage);
            DobeDWUtils.saveLog(String.valueOf(thirdPartyMap.get("billNo")),
                    "致远", messageBody.toJSONString(), e.getMessage(),
                    false, "调用推送OA消息接口");
            throw new RuntimeException(e);
        }

    }



    /**
     * model值转Long
     */
    public static long l(Object value) {
        if (value == null) {
            return 0L;
        } else if (value instanceof Long) {
            return (Long)value;
        } else if (value instanceof Number) {
            return ((Number)value).longValue();
        } else if (value instanceof Boolean) {
            return ((Boolean)value).booleanValue() ? 1L : 0L;
        } else if (value instanceof Date) {
            return ((Date)value).getTime();
        } else {
            String s = value.toString().trim();
            if (s.length() == 0) {
                return 0L;
            } else {
                return Long.parseLong(s);
            }
        }
    }
}