<?php
/**
 * Contract for PayPal account persistence.
 *
 * @since   1.0.0
 * @package DonationRouter
 */

declare( strict_types=1 );
namespace DonationRouter;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Defines read/write operations for PayPal account records.
 *
 * Implementations live in includes/Infrastructure/Repositories/.
 *
 * @since 1.0.0
 */
interface Account_Repository_Interface {

	/**
	 * Retrieve a single account by its primary key.
	 *
	 * @since 1.0.0
	 *
	 * @param  int $account_id  Database row ID.
	 *
	 * @return PayPal_Account
	 *
	 * @throws Account_Not_Found_Exception  When no account matches the given ID.
	 */
	public function find_by_id( int $account_id ): PayPal_Account;

	/**
	 * Retrieve a single account by its PayPal merchant ID.
	 *
	 * @since 1.0.0
	 *
	 * @param  string $merchant_id  PayPal-assigned merchant identifier.
	 *
	 * @return PayPal_Account
	 *
	 * @throws Account_Not_Found_Exception  When no account matches the given merchant ID.
	 */
	public function find_by_merchant_id( string $merchant_id ): PayPal_Account;

	/**
	 * Locate the account for a merchant in a specific PayPal environment.
	 *
	 * @since 1.1.0
	 *
	 * @param  string $merchant_id  PayPal-assigned merchant identifier.
	 * @param  string $mode         'live' or 'sandbox'.
	 *
	 * @return PayPal_Account
	 *
	 * @throws Account_Not_Found_Exception  When no account matches the merchant ID and mode.
	 */
	public function find_by_merchant_id_and_mode( string $merchant_id, string $mode ): PayPal_Account;

	/**
	 * Return all accounts (active and inactive), ordered by account_label ascending.
	 *
	 * @since 1.0.0
	 *
	 * @return PayPal_Account[]
	 */
	public function find_all(): array;

	/**
	 * Return all active accounts, ordered by account_label ascending.
	 *
	 * @since 1.0.0
	 *
	 * @return PayPal_Account[]
	 */
	public function find_all_active(): array;

	/**
	 * Persist a new or existing account and return its row ID.
	 *
	 * @since 1.0.0
	 *
	 * @param  PayPal_Account $account  The account to save.
	 *
	 * @return int  The inserted or updated row ID.
	 *
	 * @throws Persistence_Exception  When the database write fails.
	 */
	public function save( PayPal_Account $account ): int;

	/**
	 * Mark an account inactive by its primary key.
	 *
	 * @since 1.0.0
	 *
	 * @param  int $account_id  Database row ID.
	 *
	 * @return bool  True if at least one row was updated.
	 */
	public function deactivate( int $account_id ): bool;

	/**
	 * Mark an account active by its primary key.
	 *
	 * @since 1.1.0
	 *
	 * @param  int $account_id  Database row ID.
	 *
	 * @return bool  True if at least one row was updated.
	 */
	public function activate( int $account_id ): bool;

	/**
	 * Permanently delete an account row by its primary key.
	 *
	 * @since 1.1.0
	 *
	 * @param  int $account_id  Database row ID.
	 *
	 * @return bool  True if a row was deleted.
	 */
	public function delete( int $account_id ): bool;

	/**
	 * Set (or clear) the PayPal webhook ID for an account.
	 *
	 * @since 1.1.0
	 *
	 * @param  int         $account_id  Database row ID.
	 * @param  string|null $webhook_id  PayPal webhook ID, or null to clear it.
	 *
	 * @return bool  True if a row was updated.
	 *
	 * @throws Persistence_Exception  When the update fails.
	 */
	public function update_webhook_id( int $account_id, ?string $webhook_id ): bool;
}
