package com.malk.pro.service.aliwork;

import com.malk.pro.service.dingtalk.DynamicDDService;
import com.malk.pro.tenant.TenantContext;
import com.malk.pro.tenant.TenantProfile;
import com.malk.pro.tenant.VendorCredential;
import com.malk.server.aliwork.YDAuth;
import com.malk.server.aliwork.YDConf;
import com.malk.server.common.McException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Optional;

/**
 * 多租户宜搭服务（mjava-pro 容器）
 *
 * <p>capability: multi-tenant-runtime。从 {@link TenantContext} 取当前租户的宜搭凭据，
 * 构造 {@link YDAuth} 供 {@code YDClient_Form} / {@code YDClient_Process} 原子接口使用。</p>
 *
 * <p>调用方范式：</p>
 * <pre>
 * &#64;Autowired DynamicYDService ydService;
 * &#64;Autowired YDClient_Form ydForm;
 * ...
 * ydForm.searchForm(ydService.buildAuth(), formUuid, ...);
 * </pre>
 *
 * <p>宜搭凭据约定：{@code VendorCredential.extra} 必填 {@code appType} / {@code systemToken}，
 * 可选 {@code userId}（缺省走 {@link YDConf#PUB_ACCOUNT}）。</p>
 */
@Slf4j
@Service
public class DynamicYDService {

    private static final String VENDOR = "aliwork";

    @Autowired
    private DynamicDDService ddService;

    /**
     * 当前租户宜搭凭据。租户/凭据缺失抛 {@link McException}。
     */
    public VendorCredential currentCredential() {
        TenantProfile profile = TenantContext.current();
        if (profile == null) {
            throw new McException("TENANT_REQUIRED", "TenantContext 未注入，无法获取宜搭凭据");
        }
        VendorCredential credential = profile.credential(VENDOR);
        if (credential == null) {
            throw new McException("VENDOR_NOT_CONFIGURED",
                    "tenant=" + profile.getTenantId() + " 未配置 aliwork 凭据");
        }
        return credential;
    }

    /**
     * 构造 {@link YDAuth}：accessToken 取自钉钉租户，appType/systemToken/userId 取自宜搭 extra。
     */
    public YDAuth buildAuth() {
        return buildAuth(null);
    }

    /**
     * 构造 {@link YDAuth} 并指定操作人 userId（覆盖 extra 中的默认 userId）。
     */
    public YDAuth buildAuth(String userIdOverride) {
        VendorCredential credential = currentCredential();
        Map<String, Object> extra = Optional.ofNullable(credential.getExtra()).orElseThrow(() ->
                new McException("YDA_CONFIG_INCOMPLETE",
                        "tenant=" + TenantContext.currentTenantId() + " aliwork.extra 缺失 appType/systemToken"));
        String appType = stringValue(extra, "appType");
        String systemToken = stringValue(extra, "systemToken");
        if (appType == null || systemToken == null) {
            throw new McException("YDA_CONFIG_INCOMPLETE",
                    "tenant=" + TenantContext.currentTenantId() + " 宜搭 extra 缺少 appType/systemToken");
        }
        String userId = userIdOverride != null ? userIdOverride
                : Optional.ofNullable(stringValue(extra, "userId")).orElse(YDConf.PUB_ACCOUNT);
        return YDAuth.builder()
                .accessToken(ddService.getAccessToken())
                .appType(appType)
                .systemToken(systemToken)
                .userId(userId)
                .build();
    }

    private static String stringValue(Map<String, Object> map, String key) {
        Object v = map.get(key);
        return v == null ? null : v.toString();
    }
}
