<?php
/**
 * 1x1 transparent PNG pixel for email open tracking.
 *
 * @package SuiteMkt3k
 */

namespace SuiteMkt3k\Tracking;

use SuiteMkt3k\Installer;
use SuiteMkt3k\Modules\Newsletter\Newsletter_Manager;
use SuiteMkt3k\Modules\Statistics\Stats_Collector;

defined( 'ABSPATH' ) || exit;
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching

final class Pixel {

	public static function register(): void {
		add_action( 'rest_api_init', array( __CLASS__, 'register_route' ) );
	}

	public static function register_route(): void {
		register_rest_route(
			SUITEMKT3K_REST_NAMESPACE,
			'/track/open/(?P<hash>[a-f0-9]{64})',
			array(
				'methods'             => 'GET',
				'permission_callback' => '__return_true',
				'callback'            => array( __CLASS__, 'handle' ),
				'args'                => array(
					'hash' => array(
						'sanitize_callback' => static fn( $v ) => preg_replace( '/[^a-f0-9]/', '', strtolower( (string) $v ) ),
					),
				),
			)
		);
	}

	public static function handle( \WP_REST_Request $request ) {
		$hash = (string) $request->get_param( 'hash' );
		self::record_open( $hash );

		$png = base64_decode( 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=' );
		nocache_headers();
		$response = new \WP_REST_Response( null, 200 );
		$response->header( 'Content-Type', 'image/png' );
		$response->header( 'Content-Length', (string) strlen( $png ) );
		echo $png; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		exit;
	}

	private static function record_open( string $hash ): void {
		if ( strlen( $hash ) !== 64 ) {
			return;
		}
		global $wpdb;
		$table = Newsletter_Manager::recipients_table();
		$row = $wpdb->get_row( $wpdb->prepare( 'SELECT id, newsletter_id, opened_at FROM %i WHERE tracking_hash = %s', $table, $hash ), ARRAY_A );
		if ( ! $row ) {
			self::record_cart_open( $hash );
			return;
		}
		if ( null === $row['opened_at'] ) {
			$wpdb->update( $table, array( 'opened_at' => current_time( 'mysql', true ) ), array( 'id' => (int) $row['id'] ), array( '%s' ), array( '%d' ) );
			$wpdb->query( $wpdb->prepare( 'UPDATE %i SET opens_count = opens_count + 1 WHERE id = %d', Newsletter_Manager::table(), (int) $row['newsletter_id'] ) );
			Stats_Collector::record(
				array(
					'event_type'  => 'open',
					'entity_type' => 'newsletter',
					'entity_id'   => (int) $row['newsletter_id'],
				)
			);
		}
	}

	private static function record_cart_open( string $hash ): void {
		global $wpdb;
		$events_table = Installer::table( 'events' );
		$like = '%' . $wpdb->esc_like( '"tracking_hash":"' . $hash . '"' ) . '%';
		$sent = $wpdb->get_row(
			$wpdb->prepare(
				'SELECT entity_id FROM %i WHERE event_type = %s AND entity_type = %s AND meta_json LIKE %s ORDER BY id DESC LIMIT 1',
				$events_table,
				'sent',
				'cart',
				$like
			),
			ARRAY_A
		);
		$cart_id = isset( $sent['entity_id'] ) ? (int) $sent['entity_id'] : 0;
		if ( $cart_id <= 0 ) {
			return;
		}
		$already = (int) $wpdb->get_var(
			$wpdb->prepare(
				'SELECT COUNT(*) FROM %i WHERE event_type = %s AND entity_type = %s AND entity_id = %d AND meta_json LIKE %s',
				$events_table,
				'open',
				'cart',
				$cart_id,
				$like
			)
		);
		if ( $already > 0 ) {
			return;
		}
		Stats_Collector::record(
			array(
				'event_type'  => 'open',
				'entity_type' => 'cart',
				'entity_id'   => $cart_id,
				'meta'        => array( 'tracking_hash' => $hash ),
			)
		);
	}
}
