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

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

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

defined( 'ABSPATH' ) || exit;


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

	/**
	 * Dispatch 'invoice.downloaded'.
	 *
	 * @since 3.0.0
	 *
	 * @param string   $dispatch Subtopic to dispatch ('downloaded').
	 * @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->invoice_downloaded( $webhook, $arg );
	}


	/**
	 * Webhook for invoice downloaded.
	 *
	 * @since 1.0
	 * @since 2.3.0 Use fast_events_json_encode.
	 *
	 * @param stdClass $webhook          Detailed information on the webhook.
	 * @param array    $download_info    Array with order_id, time of download, and ip-address.
	 */
	private function invoice_downloaded( stdClass $webhook, array $download_info ): void {

		$this->webhook = $webhook;

		$order = $this->get_order( absint( $download_info[0] ) );
		if ( is_array( $order ) ) {
			$this->logger->error( __( 'Order not found', 'fast-events' ), $order );
			return;
		}

		$this->deliver(
			array(
				'order_id'       => absint( $download_info[0] ),
				'event_id'       => (int) $order->event_id,
				'event_date'     => $order->event_date,
				'payment_id'     => $order->payment_id,
				'payment_status' => $order->payment_status,
				'custom_status'  => $order->custom_status,
				'created_at'     => $order->created_at,
				'downloaded_at'  => $download_info[1],
				'uid'            => $order->uid,
				'name'           => $order->name,
				'email'          => $order->email,
				'num_tickets'    => (int) $order->num_tickets,
				'total'          => (float) $order->total,
				'ip_address'     => sanitize_text_field( $download_info[2] ),
			)
		);
	}


	/**
	 * Order lookup.
	 *
	 * @since 1.0
	 *
	 * @param int $order_id    Order identifier.
	 *
	 * @return stdClass|array
	 */
	private function get_order( int $order_id ): array|stdClass {
		global $wpdb;

		$order = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}fe_event_orders WHERE id=%d", $order_id ) );
		if ( null === $order ) {
			$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}fe_event_webhooks SET pending=GREATEST(0, pending-1) WHERE id = %d", (int) $this->webhook->id ) );
			return array(
				'type'       => 'Webhook',
				'webhook-id' => (int) $this->webhook->id,
				'name'       => $this->webhook->name,
				'url'        => $this->webhook->url,
				'topic'      => $this->webhook->topic,
				'error'      => '** Order #' . $order_id . ' not found **',
			);
		}

		return $order;
	}
}
