/**
 * Account Credential Manager Types
 *
 * Port interface for managing OAuth credentials for agent accounts.
 * The credential manager reads, validates, refreshes, and persists tokens,
 * emitting events on state changes.
 */

/**
 * OAuth credentials stored in the account's config directory.
 */
export interface OAuthCredentials {
  accessToken: string;
  refreshToken: string | null;
  /** Expiry time in milliseconds since epoch. Null for setup tokens with no expiry. */
  expiresAt: number | null;
  subscriptionType: string | null;
  rateLimitTier: string | null;
}

/**
 * Result of a token refresh attempt.
 */
export interface RefreshResult {
  accessToken: string;
  refreshToken: string;
  /** Token lifetime in seconds */
  expiresIn: number;
}

/**
 * Result of credential validation or ensureValid operation.
 */
export interface CredentialValidationResult {
  /** Whether credentials are currently valid and usable */
  valid: boolean;
  /** Current credentials if valid, null otherwise */
  credentials: OAuthCredentials | null;
  /** Error message if validation failed */
  error: string | null;
  /** Whether credentials were refreshed during this operation */
  refreshed: boolean;
}

/**
 * Port interface for account credential management.
 *
 * Implementations:
 * - DefaultAccountCredentialManager: File-based adapter using ~/.cw/accounts/<uuid>/.credentials.json
 */
export interface AccountCredentialManager {
  /**
   * Read credentials from a config directory.
   * Returns null if credentials file is missing or malformed.
   */
  read(configDir: string): Promise<OAuthCredentials | null>;

  /**
   * Check if credentials are expired or about to expire.
   * Uses a buffer (default 5 minutes) to preemptively refresh.
   */
  isExpired(credentials: OAuthCredentials): boolean;

  /**
   * Refresh an access token using the refresh token.
   * Returns null if refresh fails.
   */
  refresh(configDir: string, refreshToken: string): Promise<RefreshResult | null>;

  /**
   * Write updated credentials to the config directory.
   * Preserves other fields in the credentials file.
   */
  write(
    configDir: string,
    accessToken: string,
    refreshToken: string,
    expiresIn: number,
  ): Promise<void>;

  /**
   * Ensure credentials are valid, refreshing if needed.
   * Emits events on refresh or expiration.
   *
   * @param configDir - Path to the account's config directory
   * @param accountId - Optional account ID for event payloads
   */
  ensureValid(configDir: string, accountId?: string): Promise<CredentialValidationResult>;

  /**
   * Validate credentials without attempting refresh.
   * Useful for health checks where you want to report state without side effects.
   *
   * @param configDir - Path to the account's config directory
   * @param accountId - Optional account ID for event payloads
   */
  validate(configDir: string, accountId?: string): Promise<CredentialValidationResult>;
}
