import { Observable } from 'rxjs';
import { ExternalIdentity, ExternalIdentityProvider } from '../models/customer-identity.model';

/**
 * Providers this surface can start an OAuth authorize redirect for.
 *
 * Narrower than ExternalIdentityProvider on purpose: Telegram and MAX link
 * through a bot / QR flow owned by @marketplaces/auth, not an authorize
 * redirect, so they can be listed and unlinked here (FH-4.6) but never
 * passed to getAuthorizeUrl().
 */
export type SocialProvider = 'vk' | 'yandex';

/**
 * Per docs/backend/PHASE-8-IDENTITY-MESSAGING-CONTRACT.md §2.
 *
 * One surface, one strategy per provider behind it. The client's entire
 * involvement is "send me somewhere" and "tell me what is linked" - the
 * OAuth exchange happens backend-side and the browser never holds a client
 * secret, an access token, or a PKCE code verifier.
 *
 * Note what is absent: there is no completeCallback(). An earlier VK-only
 * version of this interface took (code, codeVerifier) from the client, which
 * forced the browser to generate and store the verifier. We are a
 * confidential client; the backend owns state and verifier, handles the
 * provider's callback itself, and redirects back with a session already set.
 */
export interface SocialIdentityGateway {
  /**
   * URL to navigate the browser to in order to start the flow. The backend
   * has already minted and stored the single-use state and code verifier by
   * the time this resolves.
   *
   * @param returnTo where to land after the callback completes, validated
   *   backend-side against the tenant's own origin - never used as an open
   *   redirect.
   */
  getAuthorizeUrl(provider: SocialProvider, returnTo?: string): Observable<string>;

  /** Providers currently linked to the authenticated customer. */
  listIdentities(): Observable<ExternalIdentity[]>;

  /**
   * Unlinks a provider from the authenticated customer. Accepts any linked
   * provider, not just the OAuth ones - a customer can detach Telegram or MAX
   * the same way they detach VK, provided at least one identity remains
   * (the backend enforces "you cannot unlink your last login").
   */
  unlink(provider: ExternalIdentityProvider): Observable<void>;
}
