<?php
/**
 * EventTicketTypeRepository
 *
 * Data access layer for event ticket types.
 *
 * @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\EventTicketType;

/**
 * Class EventTicketTypeRepository
 */
class EventTicketTypeRepository extends BaseRepository {

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

	/**
	 * Get all ticket types for a given event.
	 *
	 * @param int $event_id The event ID.
	 *
	 * @return array
	 */
	public function getByEvent( int $event_id ): array {
		return EventTicketType::where( 'event_id', $event_id )
			->orderBy( 'sort_order', 'ASC' )
			->get();
	}

	/**
	 * Get active ticket types for a given event.
	 *
	 * @param int $event_id The event ID.
	 *
	 * @return array
	 */
	public function getActive( int $event_id ): array {
		return EventTicketType::where( 'event_id', $event_id )
			->where( 'is_active', 1 )
			->orderBy( 'sort_order', 'ASC' )
			->get();
	}

	/**
	 * Increment the quantity sold for a ticket type.
	 *
	 * @param int $ticket_type_id The ticket type ID.
	 * @param int $amount         The amount to increment by.
	 *
	 * @return bool
	 */
	public function incrementSold( int $ticket_type_id, int $amount ): bool {
		$ticket = $this->findOrFail( $ticket_type_id );

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

	/**
	 * Decrement the quantity sold for a ticket type.
	 *
	 * @param int $ticket_type_id The ticket type ID.
	 * @param int $amount         The amount to decrement by.
	 *
	 * @return bool
	 */
	public function decrementSold( int $ticket_type_id, int $amount ): bool {
		$ticket = $this->findOrFail( $ticket_type_id );
		$new_qty = max( 0, (int) $ticket->quantity_sold - $amount );

		return $ticket->update(
			array(
				'quantity_sold' => $new_qty,
			)
		);
	}

	/**
	 * Check whether a ticket type has remaining capacity for the requested quantity.
	 *
	 * @param int $ticket_type_id The ticket type ID.
	 * @param int $requested_qty  The number of tickets requested.
	 *
	 * @return bool True if capacity is available, false otherwise.
	 */
	public function hasCapacity( int $ticket_type_id, int $requested_qty ): bool {
		$ticket = $this->findOrFail( $ticket_type_id );

		// Capacity of 0 means unlimited.
		if ( 0 === (int) $ticket->capacity ) {
			return true;
		}

		$remaining = (int) $ticket->capacity - (int) $ticket->quantity_sold;

		return $remaining >= $requested_qty;
	}
}
