<?php
/**
 * Contract for country routing rule persistence.
 *
 * @since   1.0.0
 * @package DonationRouter
 */

declare( strict_types=1 );
namespace DonationRouter;

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

/**
 * Defines read/write operations for country routing records.
 *
 * Implementations live in includes/Infrastructure/Repositories/.
 *
 * @since 1.0.0
 */
interface Country_Routing_Repository_Interface {

	/**
	 * Retrieve a single routing rule by its primary key.
	 *
	 * @since 1.0.0
	 *
	 * @param  int $routing_id  Database row ID.
	 *
	 * @return Country_Routing
	 *
	 * @throws Country_Routing_Not_Found_Exception  When no rule exists with the given ID.
	 */
	public function find_by_id( int $routing_id ): Country_Routing;

	/**
	 * Retrieve the routing rule for a given ISO 3166-1 alpha-2 country code.
	 *
	 * @since 1.0.0
	 *
	 * @param  string $country_code  Two-letter ISO country code (e.g. "US").
	 *
	 * @return Country_Routing
	 *
	 * @throws Country_Routing_Not_Found_Exception  When no rule exists for the country.
	 */
	public function find_by_country_code( string $country_code ): Country_Routing;

	/**
	 * Retrieve the routing rule associated with a given GiveWP form.
	 *
	 * @since 1.0.0
	 *
	 * @param  int $form_id  GiveWP donation form post ID.
	 *
	 * @return Country_Routing
	 *
	 * @throws Country_Routing_Not_Found_Exception  When no rule is associated with the form.
	 */
	public function find_by_form_id( int $form_id ): Country_Routing;

	/**
	 * Return all active routing rules ordered by sort_order ascending.
	 *
	 * @since 1.0.0
	 *
	 * @return Country_Routing[]
	 */
	public function find_all_active(): array;

	/**
	 * Return all routing rules (active and inactive) ordered by sort_order and country_code.
	 *
	 * @since 1.0.0
	 *
	 * @return Country_Routing[]
	 */
	public function find_all(): array;

	/**
	 * Return the active routing rule for a given country code, or null if none.
	 *
	 * @since 1.0.0
	 *
	 * @param  string   $country_code  ISO 3166-1 alpha-2 country code.
	 * @param  int|null $exclude_id    Routing rule ID to exclude from the check (for updates).
	 *
	 * @return Country_Routing|null
	 */
	public function find_active_by_country_excluding( string $country_code, ?int $exclude_id ): ?Country_Routing;

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

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