<?php
/**
 * EventRepository
 *
 * Data access layer for events.
 *
 * @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\Event;

/**
 * Class EventRepository
 */
class EventRepository extends BaseRepository {

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

	/**
	 * Find an event by its public-facing slug.
	 *
	 * @param string $slug The slug to search for.
	 *
	 * @return Event|null
	 */
	public function findBySlug( string $slug ) {
		$result = Event::where( 'slug', $slug )->first();

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

	/**
	 * Get all published events.
	 *
	 * @return array
	 */
	public function getPublished(): array {
		return Event::where( 'status', 'published' )
			->orderBy( 'start_date', 'ASC' )
			->get();
	}

	/**
	 * Get upcoming events (start_date >= today, published).
	 *
	 * @return array
	 */
	public function getUpcoming(): array {
		$today = current_time( 'Y-m-d' );

		return Event::where( 'status', 'published' )
			->where( 'start_date', '>=', $today )
			->orderBy( 'start_date', 'ASC' )
			->get();
	}

	/**
	 * Find all events by organizer ID.
	 *
	 * @param int $organizer_id The organizer user ID.
	 *
	 * @return array
	 */
	public function findByOrganizer( int $organizer_id ): array {
		return Event::where( 'organizer_id', $organizer_id )
			->orderBy( 'start_date', 'DESC' )
			->get();
	}

	/**
	 * Increment the registered count for an event.
	 *
	 * @param int $event_id The event ID.
	 * @param int $amount   The amount to increment by.
	 *
	 * @return bool
	 */
	public function incrementRegisteredCount( int $event_id, int $amount ): bool {
		$event = $this->findOrFail( $event_id );

		return $event->update(
			array(
				'registered_count' => (int) $event->registered_count + $amount,
			)
		);
	}

	/**
	 * Decrement the registered count for an event.
	 *
	 * @param int $event_id The event ID.
	 * @param int $amount   The amount to decrement by.
	 *
	 * @return bool
	 */
	public function decrementRegisteredCount( int $event_id, int $amount ): bool {
		$event = $this->findOrFail( $event_id );
		$new_count = max( 0, (int) $event->registered_count - $amount );

		return $event->update(
			array(
				'registered_count' => $new_count,
			)
		);
	}
}
