/**
 * K3Cloud WebAPI Java 客户端骨架
 * 语言：Java 11+ (java.net.http.HttpClient)
 * 覆盖：登录/查询/查看/保存/删除/提交/审核/反审核/下推/自定义操作
 * 依赖：Jackson Databind (com.fasterxml.jackson.core:jackson-databind)
 *
 * 使用说明：
 * 1. 替换 serverUrl / acctId / appId / appSecret 为实际值
 * 2. 首次调用 loginByAppSecret() 建立会话，后续请求自动携带 Cookie
 */
package com.mycompany.integration;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;

import java.net.URI;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse.BodyHandlers;
import java.util.HashMap;
import java.util.Map;

public class K3CloudClient {

    private final String serverUrl;
    private final HttpClient httpClient;
    private final ObjectMapper objectMapper = new ObjectMapper();

    public K3CloudClient(String serverUrl) {
        this.serverUrl = serverUrl;
        CookieManager cookieManager = new CookieManager();
        cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
        this.httpClient = HttpClient.newBuilder()
                .cookieHandler(cookieManager)
                .build();
    }

    private JsonNode post(String serviceName, Object... args) throws Exception {
        String url = serverUrl + serviceName + ".common.kdsvc";
        String body = objectMapper.writeValueAsString(args);

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .POST(BodyPublishers.ofString(body))
                .build();

        HttpResponse<String> response = httpClient.send(request, BodyHandlers.ofString());
        return objectMapper.readTree(response.body());
    }

    /** 应用授权登录（推荐） */
    public JsonNode loginByAppSecret(String acctId, String appId, String appSecret, int lcid) throws Exception {
        return post(
            "Kingdee.BOS.WebApi.ServicesStub.AuthService.LoginByAppSecret",
            acctId, appId, appSecret, lcid
        );
    }

    /** 用户密码登录 */
    public JsonNode loginByUser(String dbId, String userName, String password, int lcid) throws Exception {
        return post(
            "Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser",
            dbId, userName, password, lcid
        );
    }

    /** 单据查询（返回二维数组） */
    public JsonNode executeBillQuery(String formId, String fieldKeys, String filterString, int startRow, int limit) throws Exception {
        Map<String, Object> data = new HashMap<>();
        data.put("FormId", formId);
        data.put("FieldKeys", fieldKeys);
        data.put("FilterString", filterString != null ? filterString : "");
        data.put("StartRow", startRow);
        data.put("Limit", limit);
        return post(
            "Kingdee.BOS.WebApi.ServicesStub.BusinessDataService.ExecuteBillQuery",
            data
        );
    }

    /** 查看单据详情 */
    public JsonNode view(String formId, long keyValue) throws Exception {
        Map<String, Object> data = new HashMap<>();
        data.put("CreateOrgId", 0);
        data.put("Number", "");
        data.put("Id", keyValue);
        return post(
            "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.View",
            formId, objectMapper.writeValueAsString(data)
        );
    }

    /** 保存单据 */
    public JsonNode save(String formId, Object model) throws Exception {
        Map<String, Object> data = new HashMap<>();
        data.put("Model", model);
        data.put("IsDeleteEntry", "true");
        data.put("ValidateFlag", "true");
        data.put("NumberSearch", "true");
        return post(
            "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Save",
            formId, objectMapper.writeValueAsString(data)
        );
    }

    /** 删除单据 */
    public JsonNode delete(String formId, long[] keyValues) throws Exception {
        Map<String, Object> data = new HashMap<>();
        data.put("CreateOrgId", 0);
        data.put("Numbers", "");
        data.put("Ids", joinIds(keyValues));
        return post(
            "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Delete",
            formId, objectMapper.writeValueAsString(data)
        );
    }

    /** 提交单据 */
    public JsonNode submit(String formId, long[] keyValues) throws Exception {
        Map<String, Object> data = new HashMap<>();
        data.put("CreateOrgId", 0);
        data.put("Numbers", "");
        data.put("Ids", joinIds(keyValues));
        return post(
            "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Submit",
            formId, objectMapper.writeValueAsString(data)
        );
    }

    /** 审核单据 */
    public JsonNode audit(String formId, long[] keyValues) throws Exception {
        Map<String, Object> data = new HashMap<>();
        data.put("CreateOrgId", 0);
        data.put("Numbers", "");
        data.put("Ids", joinIds(keyValues));
        return post(
            "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Audit",
            formId, objectMapper.writeValueAsString(data)
        );
    }

    /** 反审核单据 */
    public JsonNode unAudit(String formId, long[] keyValues) throws Exception {
        Map<String, Object> data = new HashMap<>();
        data.put("CreateOrgId", 0);
        data.put("Numbers", "");
        data.put("Ids", joinIds(keyValues));
        return post(
            "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.UnAudit",
            formId, objectMapper.writeValueAsString(data)
        );
    }

    /** 下推单据 */
    public JsonNode push(String targetFormId, String keyValues, String ruleId) throws Exception {
        Map<String, Object> data = new HashMap<>();
        data.put("Ids", keyValues);
        data.put("RuleId", ruleId != null ? ruleId : "");
        data.put("TargetFormId", targetFormId);
        data.put("IsEnableDefaultRule", "true");
        return post(
            "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Push",
            objectMapper.writeValueAsString(data)
        );
    }

    /** 执行自定义操作 */
    public JsonNode executeOperation(String formId, String opNumber, long[] keyValues) throws Exception {
        Map<String, Object> data = new HashMap<>();
        data.put("CreateOrgId", 0);
        data.put("Numbers", "");
        data.put("Ids", joinIds(keyValues));
        return post(
            "Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExcuteOperation",
            formId, opNumber, objectMapper.writeValueAsString(data)
        );
    }

    private String joinIds(long[] ids) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < ids.length; i++) {
            if (i > 0) sb.append(",");
            sb.append(ids[i]);
        }
        return sb.toString();
    }
}
