import type { Repository } from '../../db/repository.js';
import { makeOidcAdapterFactory } from './oidc-adapter.js';
import { loadOrCreateJwks } from './oidc-keys.js';

/** oidc-provider の Configuration の構造的最小型（@types に依存しない）。 */
export interface A2aOidcConfig {
  adapter: (name: string) => unknown;
  jwks: { keys: object[] };
  scopes: string[];
  clientDefaults?: Record<string, unknown>;
  cookies?: { keys: string[] };
  pkce?: { required?: (ctx: unknown, client: unknown) => boolean };
  features?: {
    introspection?: { enabled: boolean };
    revocation?: { enabled: boolean };
    resourceIndicators?: {
      enabled: boolean;
      defaultResource?: (ctx: unknown) => string;
      getResourceServerInfo?: (ctx: unknown, resourceIndicator: string, client: unknown) => Record<string, unknown>;
      useGrantedResource?: () => boolean;
    };
    devInteractions?: { enabled: boolean };
  };
  interactions?: { url: (ctx: unknown, interaction: { uid: string }) => string };
  findAccount?: (ctx: unknown, sub: string) => Promise<{ accountId: string; claims: () => Record<string, unknown> } | undefined>;
  ttl?: Record<string, number>;
}

export interface BuildA2aOidcConfigDeps {
  repo: Repository;
  secretsDir: string;
  resourceAudience: string;   // A2A endpoint 絶対 URL。audience として固定
  cookieKeys: string[];       // 既存 session secret 由来
}

export const A2A_READ_SCOPE = 'a2a.read';

export function buildA2aOidcConfig(deps: BuildA2aOidcConfigDeps): A2aOidcConfig {
  const { repo, secretsDir, resourceAudience, cookieKeys } = deps;
  return {
    adapter: makeOidcAdapterFactory(repo),
    jwks: loadOrCreateJwks(secretsDir),
    scopes: ['openid', A2A_READ_SCOPE],
    clientDefaults: {
      grant_types: ['authorization_code'],
      response_types: ['code'],
      token_endpoint_auth_method: 'none', // public client + PKCE（Task 3 メモ参照）
    },
    cookies: { keys: cookieKeys },
    pkce: { required: () => true },
    features: {
      introspection: { enabled: true },
      revocation: { enabled: true },
      devInteractions: { enabled: false }, // 既定の dev 画面を無効化し自前 consent を使う
      resourceIndicators: {
        enabled: true,
        defaultResource: () => resourceAudience,
        useGrantedResource: () => true,
        getResourceServerInfo: (_ctx, _resourceIndicator, _client) => ({
          audience: resourceAudience,
          scope: A2A_READ_SCOPE,
          accessTokenFormat: 'opaque', // introspection で検証する。JWT にしない
          accessTokenTTL: 10 * 60,     // 10 分
        }),
      },
    },
    interactions: {
      url: (_ctx, interaction) => `/oidc/interaction/${interaction.uid}`,
    },
    findAccount: async (_ctx, sub) => ({
      accountId: sub,
      claims: () => ({ sub }),
    }),
    ttl: {
      AccessToken: 10 * 60,
      AuthorizationCode: 5 * 60,
      Grant: 14 * 24 * 60 * 60,
      Interaction: 60 * 60,
      Session: 14 * 24 * 60 * 60,
    },
  };
}
