<?php
/**
 * A class to deliver scan-related topics to a webhook.
 *
 * @since 3.0.0
 */

declare( strict_types=1 );
namespace FeData\FastEvents\Hooks\Webhooks\Topic;

use FeData\FastEvents\Helpers\SeatsHelper;
use FeData\FastEvents\Hooks\Webhooks\AbstractWebhook;
use stdClass;

defined( 'ABSPATH' ) || exit;


/**
 * A class to deliver scan-related topics to a webhook.
 */
final class ScanTopic extends AbstractWebhook {

	/**
	 * Dispatch 'scan.created'.
	 *
	 * @since 3.0.0
	 *
	 * @param string   $dispatch Subtopic to dispatch ('created').
	 * @param stdClass $webhook  Detailed information on the webhook.
	 * @param mixed    $arg      Event identifier (int).
	 */
	public function dispatch( string $dispatch, stdClass $webhook, mixed $arg ): void {
		$this->created_scan( $webhook, $arg );
	}


	/**
	 * Webhook for a new scan.
	 *
	 * @since 1.0
	 * @since 2.3.0 Use fast_events_json_encode.
	 *
	 * @param stdClass $webhook     Detailed information on the webhook.
	 * @param mixed    $arg         Qrcode and level scan of the ticket.
	 */
	private function created_scan( stdClass $webhook, mixed $arg ): void {
		global $wpdb;
		global $fevt_container;

		$this->webhook = $webhook;
		$ticket_id     = $arg[0];  // Unique id of the ticket.
		$scan_level    = $arg[1];  // Scan level.
		$entry_id      = $arg[2];  // The unique id in the entry table (used for all scan levels except 0).

		// Look up the scan.
		$event_table  = $wpdb->prefix . 'fe_events';
		$order_table  = $wpdb->prefix . 'fe_event_orders';
		$qrcode_table = $wpdb->prefix . 'fe_event_qrcodes';
		$entry_table  = $wpdb->prefix . 'fe_event_entries';
		// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		if ( 0 === $scan_level ) {
			$result = $wpdb->get_row(
				$wpdb->prepare(
					"SELECT $qrcode_table.id, $qrcode_table.ticket_type, $qrcode_table.event_id, $qrcode_table.scan_date, " .
					"$qrcode_table.qrcode, $qrcode_table.order_id, $qrcode_table.scan_location, $order_table.name, $order_table.email, " .
					"$event_table.seats_needed " .
					"FROM $qrcode_table " .
					"INNER JOIN $order_table ON $order_table.id = $qrcode_table.order_id " .
					"INNER JOIN $event_table ON $event_table.id = $qrcode_table.event_id " .
					"WHERE $qrcode_table.id = %d",
					$ticket_id
				)
			);
		} else {
			$result = $wpdb->get_row(
				$wpdb->prepare(
					"SELECT $qrcode_table.id, $qrcode_table.ticket_type, $qrcode_table.event_id, $entry_table.scan_date, " .
					"$qrcode_table.qrcode, $qrcode_table.order_id, $entry_table.scan_location, $order_table.name, $order_table.email, " .
					"$event_table.seats_needed " .
					"FROM $qrcode_table " .
					"INNER JOIN $order_table ON $order_table.id = $qrcode_table.order_id " .
					"INNER JOIN $event_table ON $event_table.id = $qrcode_table.event_id " .
					"INNER JOIN $entry_table ON $entry_table.id = %d " .
					"WHERE $qrcode_table.id = %d",
					$entry_id,
					$ticket_id
				)
			);
		}
		// phpcs:enable

		// No result?
		if ( null === $result ) {
			$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}fe_event_webhooks SET pending=GREATEST(0, pending-1) WHERE id = %d", (int) $this->webhook->id ) );
			$this->logger->error(
				'** Ticket #' . $ticket_id . ' not found **',
				array(
					'type'       => 'Webhook',
					'webhook-id' => (int) $this->webhook->id,
					'name'       => $this->webhook->name,
					'url'        => $this->webhook->url,
					'topic'      => $this->webhook->topic,
				)
			);
			return;
		}

		// Do we use seats?
		if ( 1 === (int) $result->seats_needed ) {
			$seats       = $fevt_container->get( SeatsHelper::class );
			$ticket_type = $result->ticket_type . $seats->get_seat( (int) $result->event_id, $result->qrcode );
		} else {
			$ticket_type = $result->ticket_type;
		}

		$this->deliver(
			array(
				'event_id'      => (int) $result->event_id,
				'order_id'      => (int) $result->order_id,
				'name'          => $result->name,
				'email'         => $result->email,
				'qrcode'        => $result->qrcode,
				'ticket_type'   => $ticket_type,
				'scan_level'    => $scan_level,
				'scan_date'     => $result->scan_date,
				'scan_location' => $result->scan_location,
			)
		);
	}
}
