<?php
/**
 * Blocks live automations on staging/dev unless explicitly overridden.
 *
 * wp-config.php overrides:
 *   define( 'CARTCUE_PREVENT_WORKFLOWS', true );  — force block
 *   define( 'CARTCUE_ALLOW_WORKFLOWS', true );    — force allow (QA on staging)
 *
 * @package CartCue
 */

namespace CartCue;

defined( 'ABSPATH' ) || exit;

final class EnvironmentGuard {

	/** @var list<string> */
	private const NON_PRODUCTION_ENV_TYPES = [ 'development', 'staging', 'local' ];

	/** Action slugs that call external HTTP APIs (not wp_mail). */
	private const EXTERNAL_OUTBOUND_ACTIONS = [
		'webhook',
		'send_sms',
		'send_whatsapp',
		'slack_notification',
		'mailchimp_subscribe',
		'mailchimp_unsubscribe',
		'mailchimp_add_tag',
		'mailchimp_remove_tag',
		'fluentcrm_add_contact',
		'fluentcrm_add_tag',
		'fluentcrm_remove_tag',
		'mailpoet_subscribe',
		'mailpoet_unsubscribe',
		'activecampaign_subscribe',
		'activecampaign_add_tag',
		'klaviyo_add_profile',
		'klaviyo_track_event',
	];

	public static function init(): void {
		add_action( 'admin_notices', [ __CLASS__, 'render_admin_notice' ] );
	}

	public static function default_settings(): array {
		return [
			'block_non_production_sends'       => '1',
			'allow_outbound_on_non_production' => '0',
		];
	}

	public static function get_environment_type(): string {
		if ( function_exists( 'wp_get_environment_type' ) ) {
			return (string) wp_get_environment_type();
		}
		return 'production';
	}

	public static function is_non_production_environment(): bool {
		return in_array( self::get_environment_type(), self::NON_PRODUCTION_ENV_TYPES, true );
	}

	public static function is_force_blocked(): bool {
		return defined( 'CARTCUE_PREVENT_WORKFLOWS' ) && CARTCUE_PREVENT_WORKFLOWS;
	}

	public static function is_force_allowed(): bool {
		return defined( 'CARTCUE_ALLOW_WORKFLOWS' ) && CARTCUE_ALLOW_WORKFLOWS;
	}

	public static function setting_blocks_non_production(): bool {
		$s = get_option( 'cartcue_settings', [] );
		if ( ! is_array( $s ) ) {
			$s = [];
		}
		$defaults = self::default_settings();
		return '1' === (string) ( $s['block_non_production_sends'] ?? $defaults['block_non_production_sends'] );
	}

	public static function allows_outbound_on_non_production(): bool {
		$s = get_option( 'cartcue_settings', [] );
		if ( ! is_array( $s ) ) {
			$s = [];
		}
		$defaults = self::default_settings();
		return '1' === (string) ( $s['allow_outbound_on_non_production'] ?? $defaults['allow_outbound_on_non_production'] );
	}

	/**
	 * @param array<string, mixed> $data Trigger/action context; `_is_test` bypasses the guard.
	 */
	public static function is_blocked( array $data = [] ): bool {
		if ( ! empty( $data['_is_test'] ) ) {
			return false;
		}
		if ( self::is_force_allowed() ) {
			return false;
		}
		if ( self::is_force_blocked() ) {
			return true;
		}
		$blocked = self::is_non_production_environment() && self::setting_blocks_non_production();
		return (bool) apply_filters( 'cartcue_environment_guard_blocked', $blocked, $data );
	}

	/**
	 * Whether workflow triggers, queues, and customer-facing emails may run.
	 *
	 * @param array<string, mixed> $data Trigger/action context; `_is_test` bypasses the guard.
	 */
	public static function should_run_workflows( array $data = [] ): bool {
		return ! self::is_blocked( $data );
	}

	/**
	 * Whether external HTTP actions (webhooks, SMS, CRM APIs) may run.
	 *
	 * @param array<string, mixed> $data
	 */
	public static function allows_live_outbound( array $data = [] ): bool {
		if ( ! empty( $data['_is_test'] ) ) {
			return false;
		}
		if ( self::is_force_allowed() ) {
			return true;
		}
		if ( self::should_run_workflows( $data ) ) {
			return true;
		}
		if ( self::is_non_production_environment() && self::allows_outbound_on_non_production() ) {
			return true;
		}
		return false;
	}

	/**
	 * Whether wp_mail customer sends are allowed (admin test emails use `_is_test`).
	 *
	 * @param array<string, mixed> $args Mailer $args or trigger $data.
	 */
	public static function allows_live_email( array $args = [] ): bool {
		return self::should_run_workflows( $args );
	}

	public static function is_external_outbound_action( string $slug ): bool {
		return in_array( $slug, self::EXTERNAL_OUTBOUND_ACTIONS, true );
	}

	/**
	 * @param array<string, mixed> $data
	 */
	public static function should_skip_action( string $slug, array $data = [] ): bool {
		if ( ! self::is_external_outbound_action( $slug ) ) {
			return false;
		}
		return ! self::allows_live_outbound( $data );
	}

	public static function is_blocking_active(): bool {
		return ! self::should_run_workflows( [] );
	}

	public static function get_block_reason(): string {
		if ( self::is_force_blocked() && ! self::is_force_allowed() ) {
			return __( 'CARTCUE_PREVENT_WORKFLOWS is enabled in wp-config.php.', 'cartcue-sales-automation' );
		}
		if ( self::is_non_production_environment() && self::setting_blocks_non_production() && ! self::is_force_allowed() ) {
			return sprintf(
				/* translators: %s: WordPress environment type, e.g. staging */
				__( 'WordPress environment type is "%s".', 'cartcue-sales-automation' ),
				self::get_environment_type()
			);
		}
		return __( 'CartCue live sends are paused for this site.', 'cartcue-sales-automation' );
	}

	public static function render_admin_notice(): void {
		if ( ! is_admin() || ! current_user_can( 'manage_woocommerce' ) ) {
			return;
		}
		if ( ! self::is_blocking_active() ) {
			return;
		}
		$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
		if ( $screen && ! str_contains( (string) $screen->id, 'cartcue' ) ) {
			return;
		}
		echo '<div class="notice notice-warning"><p><strong>';
		esc_html_e( 'CartCue: automations paused on this environment', 'cartcue-sales-automation' );
		echo '</strong> ';
		echo esc_html( self::get_block_reason() );
		echo ' ';
		esc_html_e( 'No customer emails, SMS, webhooks, or CRM syncs will run. Test plays in the editor still work.', 'cartcue-sales-automation' );
		if ( ! self::is_force_allowed() ) {
			echo ' ';
			esc_html_e( 'To test live runs here, add define( \'CARTCUE_ALLOW_WORKFLOWS\', true ); to wp-config.php or adjust Settings → Non-production safety.', 'cartcue-sales-automation' );
		}
		echo '</p></div>';
	}
}
