<?php
/**
 * Click redirector. Validates final URL to avoid open redirects.
 *
 * @package SuiteMkt3k
 */

namespace SuiteMkt3k\Tracking;

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

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

final class Redirector {

	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/click/(?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 ) ),
					),
					'u'    => array(
						'required'          => true,
						'sanitize_callback' => 'esc_url_raw',
					),
				),
			)
		);
	}

	public static function handle( \WP_REST_Request $request ) {
		$hash = (string) $request->get_param( 'hash' );
		$url  = rawurldecode( (string) $request->get_param( 'u' ) );
		self::record_click( $hash, $url );

		$safe = wp_validate_redirect( $url, '' );
		if ( ! $safe ) {
			$safe = home_url( '/' );
		}
		wp_safe_redirect( $safe, 302 );
		exit;
	}

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

	private static function record_cart_click( string $hash, string $url ): 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;
		}
		Stats_Collector::record(
			array(
				'event_type'  => 'click',
				'entity_type' => 'cart',
				'entity_id'   => $cart_id,
				'meta'        => array(
					'url'           => $url,
					'tracking_hash' => $hash,
				),
			)
		);
	}
}
