package com.agent.management.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

/**
 * 外部 API（/api/v1/**）配置。
 *
 * <p>配置示例：
 * <pre>
 * external:
 *   api:
 *     enabled: true
 *     keys:
 *       - key: "client-a-secret"
 *         workflow-names: [research-agent, summary-flow]   # 仅允许调用指定 name 的工作流；留空表示不限制
 *       - key: "client-b-secret"
 *         workflow-names: []
 * </pre>
 *
 * <p>历史配置项 {@code workflow-ids}（按数字 id 配置）已废弃。
 * 旧配置若仍按数字 id 配置，由于迁移后 name 默认为 String.valueOf(id)，可继续按 name 形式工作；
 * 但建议尽快迁移为 kebab-case 工作流名配置。
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "external.api")
public class ExternalApiProperties {

    /** 总开关：false 时 /api/v1/** 全部返回 404 */
    private boolean enabled = true;

    /** 已注册的 API Key 列表 */
    private List<KeyEntry> keys = new ArrayList<>();

    @Data
    public static class KeyEntry {
        /** API Key（建议 32+ 字符随机字符串） */
        private String key;
        /** 允许调用的工作流 name 白名单（kebab-case）；空列表或不填表示不限制 */
        private List<String> workflowNames;
        /**
         * 已废弃：旧字段名 workflowIds（数字 id）。
         * 为兼容旧配置保留读取能力，运行时自动按数字字符串对比。
         */
        @Deprecated
        private List<Long> workflowIds;
    }

    /**
     * 校验 API Key 是否有效。
     */
    public KeyEntry lookup(String key) {
        if (key == null || key.isEmpty()) return null;
        for (KeyEntry e : keys) {
            if (key.equals(e.getKey())) return e;
        }
        return null;
    }

    /**
     * 校验 API Key 是否有权调用指定工作流（按 name + id 双重匹配）。
     *
     * <p>规则：
     * <ul>
     *   <li>新配置 workflowNames：按字符串精确匹配 name；空列表 = 不限制</li>
     *   <li>旧配置 workflowIds：按数字字符串匹配（兼容尚未迁移的配置）；空列表 = 不限制</li>
     *   <li>两者皆空时返回 true（不限制）</li>
     * </ul>
     */
    public boolean canAccess(KeyEntry entry, String workflowName, Long workflowId) {
        if (entry == null) return false;

        List<String> names = entry.getWorkflowNames();
        List<Long> ids = entry.getWorkflowIds();

        boolean namesConfigured = names != null && !names.isEmpty();
        boolean idsConfigured = ids != null && !ids.isEmpty();

        // 两者都未配置 = 不限制
        if (!namesConfigured && !idsConfigured) return true;

        // 优先匹配 name
        if (namesConfigured && workflowName != null && names.contains(workflowName)) {
            return true;
        }
        // 兼容旧 id 配置
        if (idsConfigured && workflowId != null && ids.contains(workflowId)) {
            return true;
        }
        return false;
    }
}
