<?php
namespace EM_Pro\API;

class Abilities {

	const CATEGORY_DATA = 'events-manager-pro-data';
	const CATEGORY_MANAGEMENT = 'events-manager-pro-management';

	public static function init() {
		if ( function_exists( 'wp_register_ability' ) && function_exists( 'wp_register_ability_category' ) ) {
			add_action( 'wp_abilities_api_categories_init', array( static::class, 'register_categories' ) );
			add_action( 'wp_abilities_api_init', array( static::class, 'register_abilities' ) );
		}
	}

	public static function register_categories() {
		wp_register_ability_category( static::CATEGORY_DATA, array(
			'label' => __( 'Events Manager Pro Data', 'em-pro' ),
			'description' => __( 'Read-only abilities for retrieving Events Manager Pro coupons, transactions, attendance, and RSVP data.', 'em-pro' ),
		) );
		wp_register_ability_category( static::CATEGORY_MANAGEMENT, array(
			'label' => __( 'Events Manager Pro Management', 'em-pro' ),
			'description' => __( 'Abilities that create, update, delete, or otherwise modify Events Manager Pro data.', 'em-pro' ),
		) );
	}

	public static function register_abilities() {
		static::register_data_ability( 'list-coupons', __( 'List coupons', 'em-pro' ), __( 'Retrieves Events Manager Pro coupons visible to the current manager.', 'em-pro' ), Schemas::collection_input(), array( static::class, 'list_coupons' ), array( static::class, 'can_manage_bookings' ) );
		static::register_data_ability( 'get-coupon', __( 'Get coupon', 'em-pro' ), __( 'Retrieves one Events Manager Pro coupon by ID.', 'em-pro' ), Schemas::id_input( __( 'Coupon ID.', 'em-pro' ) ), array( static::class, 'get_coupon' ), array( static::class, 'can_manage_bookings' ) );
		static::register_management_ability( 'create-coupon', __( 'Create coupon', 'em-pro' ), __( 'Creates an Events Manager Pro coupon.', 'em-pro' ), Schemas::coupon_input(), array( static::class, 'create_coupon' ), array( static::class, 'can_manage_bookings' ), array( 'destructive' => false, 'idempotent' => false ) );
		static::register_management_ability( 'update-coupon', __( 'Update coupon', 'em-pro' ), __( 'Updates an Events Manager Pro coupon.', 'em-pro' ), Schemas::coupon_input( true ), array( static::class, 'update_coupon' ), array( static::class, 'can_manage_bookings' ), array( 'destructive' => true, 'idempotent' => false ) );
		static::register_management_ability( 'delete-coupon', __( 'Delete coupon', 'em-pro' ), __( 'Deletes an Events Manager Pro coupon.', 'em-pro' ), Schemas::id_input( __( 'Coupon ID.', 'em-pro' ) ), array( static::class, 'delete_coupon' ), array( static::class, 'can_manage_bookings' ), array( 'destructive' => true, 'idempotent' => true ) );
		static::register_data_ability( 'validate-coupon', __( 'Validate coupon', 'em-pro' ), __( 'Validates an Events Manager Pro coupon and optionally quotes its discount for an event total.', 'em-pro' ), Schemas::coupon_validate_input(), array( static::class, 'validate_coupon' ), array( static::class, 'can_manage_bookings' ) );
		static::register_data_ability( 'list-event-coupons', __( 'List event coupons', 'em-pro' ), __( 'Retrieves coupons available to one event.', 'em-pro' ), Schemas::event_coupon_input( false ), array( static::class, 'list_event_coupons' ), array( static::class, 'can_manage_bookings' ) );
		static::register_management_ability( 'attach-event-coupon', __( 'Attach event coupon', 'em-pro' ), __( 'Links a coupon to one event.', 'em-pro' ), Schemas::event_coupon_input(), array( static::class, 'attach_event_coupon' ), array( static::class, 'can_manage_bookings' ), array( 'destructive' => false, 'idempotent' => true ) );
		static::register_management_ability( 'detach-event-coupon', __( 'Detach event coupon', 'em-pro' ), __( 'Unlinks a coupon from one event.', 'em-pro' ), Schemas::event_coupon_input(), array( static::class, 'detach_event_coupon' ), array( static::class, 'can_manage_bookings' ), array( 'destructive' => true, 'idempotent' => true ) );

		static::register_data_ability( 'list-transactions', __( 'List transactions', 'em-pro' ), __( 'Retrieves payment transactions visible to the current manager.', 'em-pro' ), Schemas::collection_input(), array( static::class, 'list_transactions' ), array( static::class, 'can_manage_bookings' ) );
		static::register_data_ability( 'list-booking-transactions', __( 'List booking transactions', 'em-pro' ), __( 'Retrieves payment transactions for one booking.', 'em-pro' ), Schemas::booking_transactions_input(), array( static::class, 'list_booking_transactions' ), array( static::class, 'can_manage_bookings' ) );
		static::register_data_ability( 'get-transaction', __( 'Get transaction', 'em-pro' ), __( 'Retrieves one payment transaction by ID.', 'em-pro' ), Schemas::id_input( __( 'Transaction ID.', 'em-pro' ) ), array( static::class, 'get_transaction' ), array( static::class, 'can_manage_bookings' ) );
		static::register_management_ability( 'delete-transaction', __( 'Delete transaction', 'em-pro' ), __( 'Deletes a payment transaction record.', 'em-pro' ), Schemas::id_input( __( 'Transaction ID.', 'em-pro' ) ), array( static::class, 'delete_transaction' ), array( static::class, 'can_manage_bookings' ), array( 'destructive' => true, 'idempotent' => true ) );

		static::register_data_ability( 'get-attendance', __( 'Get attendance', 'em-pro' ), __( 'Retrieves attendance status and history for a ticket booking.', 'em-pro' ), Schemas::id_input( __( 'Ticket booking ID or UUID.', 'em-pro' ) ), array( static::class, 'get_attendance' ), array( static::class, 'can_manage_bookings' ) );
		static::register_management_ability( 'set-attendance', __( 'Set attendance', 'em-pro' ), __( 'Checks a ticket booking in or out.', 'em-pro' ), Schemas::attendance_input(), array( static::class, 'set_attendance' ), array( static::class, 'can_manage_bookings' ), array( 'destructive' => true, 'idempotent' => false ) );

		static::register_data_ability( 'get-rsvp', __( 'Get RSVP status', 'em-pro' ), __( 'Retrieves RSVP status for a booking.', 'em-pro' ), Schemas::id_input( __( 'Booking ID or UUID.', 'em-pro' ) ), array( static::class, 'get_rsvp' ), array( static::class, 'is_logged_in' ) );
		static::register_management_ability( 'set-rsvp', __( 'Set RSVP status', 'em-pro' ), __( 'Updates RSVP status for a booking.', 'em-pro' ), Schemas::rsvp_input(), array( static::class, 'set_rsvp' ), array( static::class, 'is_logged_in' ), array( 'destructive' => true, 'idempotent' => false ) );
	}

	protected static function register_data_ability( $name, $label, $description, $input_schema, $execute_callback, $permission_callback = '__return_true' ) {
		static::register_ability( $name, array(
			'label' => $label,
			'description' => $description,
			'category' => static::CATEGORY_DATA,
			'input_schema' => $input_schema,
			'output_schema' => static::is_collection_ability( $name ) ? Schemas::collection_output() : Schemas::object_output(),
			'execute_callback' => $execute_callback,
			'permission_callback' => $permission_callback,
			'meta' => static::meta( array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ), $name, static::CATEGORY_DATA ),
		) );
	}

	protected static function register_management_ability( $name, $label, $description, $input_schema, $execute_callback, $permission_callback, $annotations ) {
		static::register_ability( $name, array(
			'label' => $label,
			'description' => $description,
			'category' => static::CATEGORY_MANAGEMENT,
			'input_schema' => $input_schema,
			'output_schema' => Schemas::object_output(),
			'execute_callback' => $execute_callback,
			'permission_callback' => $permission_callback,
			'meta' => static::meta( array_merge( array( 'readonly' => false ), $annotations ), $name, static::CATEGORY_MANAGEMENT ),
		) );
	}

	protected static function register_ability( $name, $args ) {
		wp_register_ability( 'events-manager-pro/' . $name, $args );
	}

	protected static function is_collection_ability( $name ) {
		return strpos( $name, 'list-' ) === 0;
	}

	protected static function meta( $annotations, $name = '', $category = '' ) {
		return array(
			'annotations' => $annotations,
			'show_in_rest' => true,
			'mcp' => array(
				'public' => (bool) apply_filters( 'emp_api_ability_mcp_public', true, $name, $annotations, $category ),
			),
		);
	}

	public static function list_coupons( $input ) {
		return Service::list_coupons( Utils::normalize_input( $input ) );
	}

	public static function get_coupon( $input ) {
		$input = Utils::normalize_input( $input );
		return Service::get_coupon( $input['id'] ?? 0 );
	}

	public static function create_coupon( $input ) {
		return Service::create_coupon( Utils::normalize_input( $input ) );
	}

	public static function update_coupon( $input ) {
		$input = Utils::normalize_input( $input );
		return Service::update_coupon( $input['id'] ?? 0, $input );
	}

	public static function delete_coupon( $input ) {
		$input = Utils::normalize_input( $input );
		return Service::delete_coupon( $input['id'] ?? 0 );
	}

	public static function validate_coupon( $input ) {
		$input = Utils::normalize_input( $input );
		return Service::validate_coupon( $input['id'] ?? 0, $input );
	}

	public static function list_event_coupons( $input ) {
		$input = Utils::normalize_input( $input );
		return Service::list_event_coupons( $input['event_id'] ?? $input['id'] ?? 0, $input );
	}

	public static function attach_event_coupon( $input ) {
		$input = Utils::normalize_input( $input );
		return Service::attach_event_coupon( $input['event_id'] ?? $input['id'] ?? 0, $input['coupon_id'] ?? 0 );
	}

	public static function detach_event_coupon( $input ) {
		$input = Utils::normalize_input( $input );
		return Service::detach_event_coupon( $input['event_id'] ?? $input['id'] ?? 0, $input['coupon_id'] ?? 0 );
	}

	public static function list_transactions( $input ) {
		return Service::list_transactions( Utils::normalize_input( $input ) );
	}

	public static function list_booking_transactions( $input ) {
		$input = Utils::normalize_input( $input );
		$input['booking_id'] = $input['booking_id'] ?? $input['id'] ?? 0;
		return Service::list_transactions( $input );
	}

	public static function get_transaction( $input ) {
		$input = Utils::normalize_input( $input );
		return Service::get_transaction( $input['id'] ?? 0 );
	}

	public static function delete_transaction( $input ) {
		$input = Utils::normalize_input( $input );
		return Service::delete_transaction( $input['id'] ?? 0 );
	}

	public static function get_attendance( $input ) {
		$input = Utils::normalize_input( $input );
		return Service::get_attendance( $input['id'] ?? 0 );
	}

	public static function set_attendance( $input ) {
		$input = Utils::normalize_input( $input );
		return Service::set_attendance( $input['id'] ?? 0, $input['action'] ?? '' );
	}

	public static function get_rsvp( $input ) {
		$input = Utils::normalize_input( $input );
		return Service::get_rsvp( $input['id'] ?? 0 );
	}

	public static function set_rsvp( $input ) {
		$input = Utils::normalize_input( $input );
		if ( !array_key_exists( 'status', $input ) ) {
			return Utils::error( 'emp_api_rsvp_status_required', __( 'RSVP status is required. Use null to clear a response.', 'em-pro' ), 400 );
		}
		return Service::set_rsvp( $input['id'] ?? 0, $input['status'] );
	}

	public static function can_manage_bookings() {
		return Utils::can_manage_bookings();
	}

	public static function is_logged_in() {
		return is_user_logged_in();
	}
}
