<?php
/**
 * Checkout blocker — runs as a rule on TrustLens_Request_Gate.
 *
 * Blocks checkout attempts from emails marked `is_blocked = 1` in the
 * customer table (unless `is_allowlisted = 1`). Gained Blocks/Store API
 * coverage in 1.3.0 via the shared Request_Gate primitive; prior versions
 * only covered Classic checkout.
 *
 * @package TrustLens
 * @since   1.0.0
 */

defined( 'ABSPATH' ) || exit;

final class TrustLens_Checkout_Blocker {

	private static ?TrustLens_Checkout_Blocker $instance = null;

	public static function instance(): TrustLens_Checkout_Blocker {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	public static function reset_instance_for_tests(): void {
		self::$instance = null;
	}

	private function __construct() {
		if ( ! get_option( 'trustlens_enable_blocking', false ) ) {
			return;
		}
		TrustLens_Request_Gate::instance()->register_rule(
			'email_blocklist',
			array( $this, 'evaluate' ),
			10
		);
	}

	public function evaluate( TrustLens_Gate_Context $ctx ): ?TrustLens_Gate_Block {
		if ( empty( $ctx->email ) ) {
			return null;
		}
		if ( ! $this->is_customer_blocked( $ctx->email ) ) {
			return null;
		}

		$message = get_option(
			'trustlens_block_message',
			__( 'We are unable to process your order at this time. Please contact support for assistance.', 'trustlens' )
		);

		$email_hash = wstl_get_email_hash( $ctx->email );
		wstl_log_event(
			$email_hash,
			'checkout_blocked',
			array(
				'email' => $ctx->email,
				'ip'    => $ctx->ip,
				'route' => $ctx->checkout_type,
			)
		);

		/**
		 * Fires when a blocked customer attempts checkout.
		 *
		 * @since 1.0.0
		 * @param string $email_hash Customer email hash.
		 * @param string $email      Customer email.
		 */
		do_action( 'trustlens/checkout_blocked', $email_hash, $ctx->email );

		return new TrustLens_Gate_Block(
			'email_blocklist',
			'email_blocked',
			$message,
			403,
			0
		);
	}

	private function is_customer_blocked( string $email ): bool {
		$email_hash = wstl_get_email_hash( $email );
		$customer   = wstl_get_customer( $email_hash );

		if ( ! $customer ) {
			return false;
		}
		if ( ! empty( $customer->is_allowlisted ) ) {
			return false;
		}
		return ! empty( $customer->is_blocked );
	}
}
