<?php
/**
 * EventRegistrationRepository
 *
 * Data access layer for event registrations.
 *
 * @package RadiusTheme\RadiusBooking\Repositories
 * @since   1.2.0
 */

namespace RadiusTheme\RadiusBooking\Repositories;

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

use RadiusTheme\RadiusBooking\Abstracts\BaseRepository;
use RadiusTheme\RadiusBooking\Models\EventRegistration;

/**
 * Class EventRegistrationRepository
 */
class EventRegistrationRepository extends BaseRepository {

	/**
	 * The model class managed by this repository.
	 *
	 * @var string
	 */
	protected string $model = EventRegistration::class;

	/**
	 * Get all registrations for a given event.
	 *
	 * @param int $event_id The event ID.
	 *
	 * @return array
	 */
	public function getByEvent( int $event_id ): array {
		return EventRegistration::where( 'event_id', $event_id )
			->orderBy( 'created_at', 'DESC' )
			->get();
	}

	/**
	 * Get paginated registrations for an event with resource transformation.
	 *
	 * @param int $event_id The event ID.
	 * @param int $per_page Items per page.
	 * @param int $page     Current page.
	 *
	 * @return array
	 */
	public function getByEventId( int $event_id, int $per_page = 15, int $page = 1 ): array {
		$registrations = EventRegistration::where( 'event_id', $event_id )
			->orderBy( 'created_at', 'DESC' )
			->get();

		$resource = new \RadiusTheme\RadiusBooking\Resources\EventRegistrationResource();
		$items    = array_map(
			function ( $reg ) use ( $resource ) {
				$hydrated = EventRegistration::hydrate( $reg );
				return $resource->transform( $hydrated ?: $reg );
			},
			$registrations
		);

		$total  = count( $items );
		$offset = ( $page - 1 ) * $per_page;
		$paged  = array_slice( $items, $offset, $per_page );

		return array(
			'data'         => $paged,
			'total'        => $total,
			'current_page' => $page,
			'last_page'    => (int) ceil( $total / $per_page ),
			'per_page'     => $per_page,
		);
	}

	/**
	 * Get all registrations for a given customer.
	 *
	 * @param int $customer_id The customer user ID.
	 *
	 * @return array
	 */
	public function getByCustomer( int $customer_id ): array {
		return EventRegistration::where( 'customer_id', $customer_id )
			->orderBy( 'created_at', 'DESC' )
			->get();
	}

	/**
	 * Find a registration by its unique registration number.
	 *
	 * @param string $registration_number The registration number.
	 *
	 * @return EventRegistration|null
	 */
	public function findByRegistrationNumber( string $registration_number ) {
		$result = EventRegistration::where( 'registration_number', $registration_number )->first();

		return $result ? EventRegistration::hydrate( $result ) : null;
	}

	/**
	 * Get all waitlisted registrations for a given event, ordered by position.
	 *
	 * @param int $event_id The event ID.
	 *
	 * @return array
	 */
	public function getWaitlisted( int $event_id ): array {
		return EventRegistration::where( 'event_id', $event_id )
			->where( 'status', 'waitlisted' )
			->orderBy( 'waitlist_position', 'ASC' )
			->get();
	}

	/**
	 * Get the next waitlisted registration for a given event.
	 *
	 * @param int $event_id The event ID.
	 *
	 * @return EventRegistration|null
	 */
	public function getNextWaitlisted( int $event_id ) {
		$result = EventRegistration::where( 'event_id', $event_id )
			->where( 'status', 'waitlisted' )
			->orderBy( 'waitlist_position', 'ASC' )
			->first();

		return $result ? EventRegistration::hydrate( $result ) : null;
	}

	/**
	 * Count confirmed registrations for a given event.
	 *
	 * @param int $event_id The event ID.
	 *
	 * @return int
	 */
	public function countConfirmed( int $event_id ): int {
		return EventRegistration::where( 'event_id', $event_id )
			->where( 'status', 'confirmed' )
			->count();
	}
}
