/**
 * Key Group Authorization Service
 *
 * Enforces model-level access control based on API key group membership.
 * Used in the request pipeline to check if an API key's groups allow
 * access to the requested model.
 *
 * If the API key is not in any group, all models are allowed (no restriction).
 * If the API key IS in a group, model access is determined by permissions:
 *   - Deny rules override allow rules
 *   - Patterns support wildcards: "gpt-*", "claude-*", "*" for all
 *   - Provider-specific rules: "openai/gpt-4"
 */

import { checkKeyModelAccess, getKeyGroupsForApiKey } from "@/lib/localDb";

export interface KeyGroupAuthResult {
  /** Whether the request is authorized */
  authorized: boolean;
  /** Human-readable reason if denied */
  reason?: string;
  /** Groups that apply to this key */
  groups: Array<{ id: string; name: string }>;
}

/**
 * Check if an API key has access to a specific model.
 * This is the main entry point for the request pipeline.
 *
 * @param apiKeyId - The API key ID from the auth pipeline
 * @param model - The model string (e.g., "gpt-4", "claude-opus-4-7")
 * @param provider - Optional provider (e.g., "openai", "anthropic")
 * @returns KeyGroupAuthResult
 */
export function authorizeKeyModelAccess(
  apiKeyId: string | undefined,
  model: string,
  provider?: string
): KeyGroupAuthResult {
  if (!apiKeyId) {
    // No API key = no restriction (public endpoint)
    return { authorized: true, groups: [] };
  }

  const groups = getKeyGroupsForApiKey(apiKeyId);
  if (groups.length === 0) {
    // Key not in any group = no restriction
    return { authorized: true, groups: [] };
  }

  const accessCheck = checkKeyModelAccess(apiKeyId, model, provider);

  if (accessCheck.allowed) {
    return {
      authorized: true,
      groups: groups.map((g) => ({ id: g.id, name: g.name })),
    };
  }

  const denyReason = accessCheck.deniedBy
    ? `Model "${model}" is denied by group permission (pattern: ${accessCheck.deniedBy.modelPattern})`
    : `Model "${model}" is not in the allowed models for your API key group(s). ` +
      `Configure group permissions or contact your administrator.`;

  return {
    authorized: false,
    reason: denyReason,
    groups: groups.map((g) => ({ id: g.id, name: g.name })),
  };
}

/**
 * Get a summary of group memberships for an API key (for dashboard display).
 */
export function getKeyGroupSummary(apiKeyId: string): {
  groups: Array<{ id: string; name: string }>;
  restricted: boolean;
} {
  const groups = getKeyGroupsForApiKey(apiKeyId);
  return {
    groups: groups.map((g) => ({ id: g.id, name: g.name })),
    restricted: groups.length > 0,
  };
}
