/**
 * Account Repository Port Interface
 *
 * Port for Account aggregate operations.
 * Accounts represent authenticated provider logins (e.g. Claude OAuth accounts)
 * used for round-robin agent spawning and usage-limit failover.
 */

import type { Account } from '../schema.js';

export interface CreateAccountData {
  email: string;
  provider?: string;   // defaults to 'claude'
  configJson?: string; // .claude.json content
  credentials?: string; // .credentials.json content
}

export interface AccountRepository {
  /** Create a new account. Generates id and sets timestamps. */
  create(data: CreateAccountData): Promise<Account>;

  /** Find an account by its ID. */
  findById(id: string): Promise<Account | null>;

  /** Find an account by email. */
  findByEmail(email: string): Promise<Account | null>;

  /** Find all accounts for a given provider. */
  findByProvider(provider: string): Promise<Account[]>;

  /**
   * Find the next available (non-exhausted) account for a provider.
   * Uses round-robin via lastUsedAt ordering (least-recently-used first).
   * Automatically clears expired exhaustion before querying.
   */
  findNextAvailable(provider: string): Promise<Account | null>;

  /** Mark an account as exhausted until a given time. */
  markExhausted(id: string, until: Date): Promise<Account>;

  /** Mark an account as available (clear exhaustion). */
  markAvailable(id: string): Promise<Account>;

  /** Update the lastUsedAt timestamp for an account. */
  updateLastUsed(id: string): Promise<Account>;

  /** Clear exhaustion for all accounts whose exhaustedUntil has passed. Returns count cleared. */
  clearExpiredExhaustion(): Promise<number>;

  /** Find all accounts. */
  findAll(): Promise<Account[]>;

  /** Update stored credentials for an account. */
  updateCredentials(id: string, credentials: string): Promise<Account>;

  /** Update both configJson and credentials for an account (used by account add upsert). */
  updateAccountAuth(id: string, configJson: string, credentials: string): Promise<Account>;

  /** Delete an account. Throws if not found. */
  delete(id: string): Promise<void>;
}
