<?php
/**
 * Repository Interface
 *
 * Defines the base contract for all data repositories in the plugin.
 * This interface implements the Repository pattern, providing a standardized
 * API for data access operations across different data sources.
 *
 * @package     WPUltimateSecurity\UltimateSecurity\Contracts
 * @since       1.0.0
 * @author      Ultimate Security Team
 * @license     GPL-2.0-or-later
 */

declare(strict_types=1);

namespace WPUltimateSecurity\UltimateSecurity\Contracts;

/**
 * Interface RepositoryInterface
 *
 * Base repository contract that all data repositories must implement.
 * Provides CRUD (Create, Read, Update, Delete) operations with a consistent
 * API that abstracts the underlying data storage mechanism.
 *
 * This interface enables:
 * - Consistent data access patterns across the application
 * - Easy mocking for unit tests
 * - Flexibility to change data storage without affecting business logic
 * - Type-safe operations with clear return types
 *
 * Example implementation:
 * ```php
 * class LogRepository implements RepositoryInterface {
 *     public function find(int $id): ?object {
 *         global $wpdb;
 *         return $wpdb->get_row(
 *             $wpdb->prepare("SELECT * FROM {$this->table} WHERE id = %d", $id)
 *         );
 *     }
 *     // ... other method implementations
 * }
 * ```
 *
 * @since 1.0.0
 */
interface RepositoryInterface
{
    /**
     * Find a single record by its primary key ID.
     *
     * Retrieves a single record from the data source matching the given ID.
     * Returns null if no record is found with the specified ID.
     *
     * @since 1.0.0
     *
     * @param int $id The primary key ID of the record to find.
     *
     * @return object|null The found record as an object, or null if not found.
     */
    public function find(int $id): ?object;

    /**
     * Find a single record by its primary key ID or throw an exception.
     *
     * Similar to find(), but throws an exception if no record is found
     * instead of returning null. Useful when a record is expected to exist.
     *
     * @since 2.0.0
     *
     * @param int $id The primary key ID of the record to find.
     *
     * @return object The found record as an object.
     *
     * @throws \RuntimeException If no record is found with the specified ID.
     */
    public function findOrFail(int $id): object;

    /**
     * Find all records matching the given criteria.
     *
     * Retrieves multiple records from the data source. When no criteria are
     * provided, returns all records. Criteria can include field values,
     * ordering, pagination, and other filters.
     *
     * Common criteria keys:
     * - 'where': Associative array of field => value conditions
     * - 'orderby': Column name to sort by
     * - 'order': Sort direction ('ASC' or 'DESC')
     * - 'limit': Maximum number of records to return
     * - 'offset': Number of records to skip
     *
     * @since 1.0.0
     *
     * @param array<string, mixed> $criteria Optional. Filtering and pagination criteria.
     *                                       Default empty array returns all records.
     *
     * @return array<int, object> Array of matching records as objects.
     */
    public function findAll(array $criteria = []): array;

    /**
     * Create a new record in the data source.
     *
     * Inserts a new record with the provided data. Returns the ID of the
     * newly created record on success, or false on failure.
     *
     * @since 1.0.0
     *
     * @param array<string, mixed> $data Associative array of column => value pairs.
     *
     * @return int|false The ID of the newly created record, or false on failure.
     */
    public function create(array $data): int|false;

    /**
     * Update an existing record.
     *
     * Modifies the record with the given ID using the provided data.
     * Only the fields specified in the data array will be updated.
     *
     * @since 1.0.0
     *
     * @param int                  $id   The primary key ID of the record to update.
     * @param array<string, mixed> $data Associative array of column => value pairs to update.
     *
     * @return bool True if the update was successful, false otherwise.
     */
    public function update(int $id, array $data): bool;

    /**
     * Delete a record by its ID.
     *
     * Permanently removes the record with the specified ID from the data source.
     * This operation cannot be undone.
     *
     * @since 1.0.0
     *
     * @param int $id The primary key ID of the record to delete.
     *
     * @return bool True if the deletion was successful, false otherwise.
     */
    public function delete(int $id): bool;

    /**
     * Count records matching the given criteria.
     *
     * Returns the total number of records that match the specified criteria.
     * When no criteria are provided, returns the total count of all records.
     *
     * This method is useful for:
     * - Pagination calculations
     * - Dashboard statistics
     * - Existence checks (count > 0)
     *
     * @since 1.0.0
     *
     * @param array<string, mixed> $criteria Optional. Filtering criteria matching
     *                                       the format used by findAll().
     *
     * @return int The number of matching records.
     */
    public function count(array $criteria = []): int;
}
