/**
 * ERP 调用门面：超时 + 重试
 * 依赖 K3CloudApiServiceImpl 或 KingdeeSdkService 提供 client。
 */
package com.example.integration.kingdee;

import com.kingdee.bos.webapi.sdk.K3CloudApi;

import java.util.List;
import java.util.concurrent.*;

public class KingdeeErpService {

    private final K3CloudApiServiceImpl apiService;
    private static final ExecutorService EXECUTOR = new ThreadPoolExecutor(
        4, 8, 60L, TimeUnit.SECONDS,
        new LinkedBlockingQueue<>(100),
        new ThreadPoolExecutor.CallerRunsPolicy()
    );

    private static final int MAX_RETRIES = 3;
    private static final long RETRY_DELAY_MS = 1000;

    public KingdeeErpService(K3CloudApiServiceImpl apiService) {
        this.apiService = apiService;
    }

    public List<List<Object>> executeBillQuery(String queryJson) {
        return withRetry(() -> apiService.getDefaultK3CloudApi().executeBillQuery(queryJson), 10);
    }

    public String save(String formId, String dataJson) {
        return withRetry(() -> apiService.getDefaultK3CloudApi().save(formId, dataJson), 30);
    }

    public String submit(String formId, String dataJson) {
        return withRetry(() -> apiService.getDefaultK3CloudApi().submit(formId, dataJson), 15);
    }

    public String push(String formId, String dataJson) {
        return withRetry(() -> apiService.getDefaultK3CloudApi().push(formId, dataJson), 30);
    }

    public String cancelAssign(String formId, String dataJson) {
        return withRetry(() -> apiService.getDefaultK3CloudApi().cancelAssign(formId, dataJson), 15);
    }

    private <T> T withRetry(Callable<T> call, int timeoutSec) {
        Exception last = null;
        for (int i = 1; i <= MAX_RETRIES; i++) {
            try {
                Future<T> f = EXECUTOR.submit(call);
                return f.get(timeoutSec, TimeUnit.SECONDS);
            } catch (Exception e) {
                last = e;
                if (i < MAX_RETRIES) {
                    try { Thread.sleep(RETRY_DELAY_MS * i); } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new RuntimeException(ie);
                    }
                }
            }
        }
        throw new RuntimeException("Kingdee API failed after retries", last);
    }
}