<?php

/**
 * Plugin Name: GreenPay™ by Green.Money
 * Description: GreenPay™ gateway for WooCommerce
 * Author: Green.Money
 * Version: 3.3.7
 * Author URI: http://www.green.money/
 * Tested up to: 7.0.0
 * WC requires at least: 4.2.0
 * WC tested up to: 10.9.1
 */

add_action('before_woocommerce_init', function () {

	if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
		\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true);
	}
});

// Exit if accessed directly.
if (! defined('ABSPATH')) {
	exit;
}

use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
use Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils;

include_once('includes/gmpg_extra_functions.php');
include_once('includes/gmpg_settings.php');
include_once('includes/class-wc-greenpay-checkout-assets.php');

class WC_GreenPay_Payments
{
	/**
	 * Initialize the plugin.
	 */
	public static function init()
	{
		add_action('plugins_loaded', array(__CLASS__, 'on_plugins_loaded'));
	}

	/**
	 * Runs on the 'plugins_loaded' hook.
	 */
	public static function on_plugins_loaded()
	{
		// Check if WooCommerce is active
		if (!class_exists('WooCommerce')) {
			require_once(ABSPATH . 'wp-admin/includes/plugin.php');

			$plugins = get_plugins();

			foreach ($plugins as $plugin_path => $plugin) {
				if ('WooCommerce' === $plugin['Name']) {
					define('HAS_WOO', true);
					break;
				}
			}
			add_action('admin_notices', array(__CLASS__, 'woocommerce_gateway_green_money_notice'));
		}


		// Declare HPOS (Custom Order Tables) Compatibility
		add_action('before_woocommerce_init', function () {
			if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
				\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true);
			}
		});

		self::includes(); // Directly call the includes method
		add_filter('woocommerce_payment_gateways', array(__CLASS__, 'add_gateway'));
		add_action('wp_head', array(__CLASS__, 'print_checkout_hydration_guard'), 0);
		add_action('wp_enqueue_scripts', array(__CLASS__, 'enqueue_checkout_hydration_guard'), 1);
		WC_GreenPay_Checkout_Assets::register_hooks();
		add_action('woocommerce_blocks_loaded', array(__CLASS__, 'woocommerce_gateway_woocommerce_block_support'));

		if (did_action('elementor/loaded')) {
			add_action('wp_enqueue_scripts', array(__CLASS__, 'enqueue_scripts_elementor'));
		} else {
			add_action('elementor/loaded', function () {
				add_action('wp_enqueue_scripts', array(__CLASS__, 'enqueue_scripts_elementor'));
			});
		}
	}

	/**
	 * Adds the GreenPay payment gateway to WooCommerce.
	 */
	public static function add_gateway($gateways)
	{
		$gateways[] = 'WC_GreenPay_Gateway';
		return $gateways;
	}

	/**
	 * Plugin includes.
	 */
	public static function includes()
	{
		if (class_exists('WC_Payment_Gateway')) {
			require_once 'includes/class-wc-gateway.php';
		}
	}

	/**
	 * Enqueue a frontend script, pointing at local dev server when available,
	 * and add crossorigin="anonymous" for React dev errors.
	 *
	 * @param string   $script_handle      Script handle, e.g. 'wc-greenpay-payments-script'
	 * @param string   $style_handle       Style handle, e.g. 'wc-greenpay-payments-style'
	 * @param string   $dev_url     Full URL to your dev server bundle, e.g. 'http://localhost:3000/dist/greenpay.js'
	 * @param string   $build_url   Path inside the plugin to the built file, e.g. './plugins/woocommerce-greenpay/dist/greenpay.js'
	 * @param string   $script_path Path to the script js file
	 * @param string   $style_path  Path to the style css file
	 * @param string   $asset_path  Path to the asset php file
	 */
	public static function gmpg_enqueue_dev_script($script_handle, $style_handle, $dev_url, $build_url, $script_path, $style_path, $asset_path)
	{
		$env = get_site_url();
		// Check for test server
		$is_dev = $env == 'http://localhost:8881';

		if ($is_dev) {
			$script_url = $dev_url . $script_path;
			$style_url = $dev_url . $style_path;
			$asset_url = $dev_url . $asset_path;
			wp_script_add_data($script_handle, 'crossorigin', 'anonymous');
		} else {
			$script_url = $build_url . $script_path;
			$style_url = $build_url . $style_path;
			$asset_url = $build_url . $asset_path;
		}

		$asset_fs_path = self::plugin_abspath() . ltrim($asset_path, '/');
		$asset = file_exists($asset_fs_path)
			? require($asset_fs_path)
			: array(
				'dependencies' => array('wp-element', 'wp-data', 'wp-editor'),
				'version' => time()
			);

		$deps = array_unique(array_merge(
			$asset['dependencies'],
			array('wc-settings', 'wc-blocks-registry')
		));
		$version = $asset['version'];

		wp_register_style($style_handle, $style_url, array(), $version);
		wp_enqueue_style($style_handle);

		wp_register_script($script_handle, $script_url, $deps, $version, true);
		wp_enqueue_script($script_handle);

		// Classic checkout does not load WC Blocks bundles, which normally supply React.
		if (wp_script_is($script_handle, 'enqueued')) {
			wp_enqueue_script('react');
			wp_enqueue_script('react-dom');
		}
	}

	/**
	 * Helper function to enqueue front end scripts
	 */
	public static function enqueue_scripts_helper()
	{
		$script_handle = 'wc-greenpay-payments-script';
		$style_handle = 'wc-greenpay-payments-style';
		$script_path = '/dist/greenpay.js';
		$style_path = '/dist/greenpay.css';
		$script_deps_path = '/dist/greenpay.asset.php';

		$build_url = self::plugin_url();
		$dev_url = 'http://localhost:3000';

		self::gmpg_enqueue_dev_script($script_handle, $style_handle, $dev_url, $build_url, $script_path, $style_path, $script_deps_path);

		// Localized data passed to frontend
		$settings = get_option('gmpg_settings', []);

		wp_localize_script($script_handle, 'greenmoney_wpApiSettings', array_merge(
			[
				'clientId' => $settings['gmpg_client_id'] ?? '',
				'plaidEnabled' => $settings['gmpg_plaid_enabled'] ?? false,
				'endpoint' => $settings['gmpg_api_endpoint'] ?? '',
				'context' => 'classic',
				'title' => $settings['gmpg_title'] ?? 'GreenPay',
				'description' => $settings['gmpg_gateway_description'] ?? '',
				'extraMessage' => $settings['gmpg_extra_message'] ?? ''
			],
			function_exists('gmpg_get_bank_login_frontend_settings') ? gmpg_get_bank_login_frontend_settings() : array(),
			function_exists('gmpg_get_ribbit_frontend_settings') ? gmpg_get_ribbit_frontend_settings() : array()
		));
	}

	/**
	 * Print hydration guard as early as possible in wp_head (before wp-preferences fetch).
	 */
	public static function print_checkout_hydration_guard()
	{
		if (!self::should_load_checkout_hydration_guard()) {
			return;
		}

		echo "<script id='greenpay-checkout-hydration-guard'>(function(){if(window.__greenpayHydrationGuardInstalled)return;window.__greenpayHydrationGuardInstalled=true;window.addEventListener('unhandledrejection',function(e){var r=e.reason;if(r&&typeof r==='object'&&(r.code==='rest_not_logged_in'||(r.data&&r.data.status===401)||(typeof r.message==='string'&&r.message.indexOf('not currently logged in')!==-1))){e.preventDefault();}});})();</script>\n";
	}

	/**
	 * Whether the checkout hydration guard should load.
	 */
	private static function should_load_checkout_hydration_guard()
	{
		if (!function_exists('is_checkout') || !is_checkout()) {
			return false;
		}

		if (!class_exists(CartCheckoutUtils::class) || !CartCheckoutUtils::is_checkout_block_default()) {
			return false;
		}

		if (!function_exists('WC') || !WC()->payment_gateways()) {
			return false;
		}

		$gateways = WC()->payment_gateways()->payment_gateways();
		$gateway  = isset($gateways['greenmoney']) ? $gateways['greenmoney'] : null;

		return $gateway && $gateway->is_available();
	}

	/**
	 * Enqueue an inline head script on block checkout to swallow benign guest REST 401
	 * rejections that can stall WooCommerce cart hydration (WC #64474).
	 */
	public static function enqueue_checkout_hydration_guard()
	{
		if (!self::should_load_checkout_hydration_guard()) {
			return;
		}

		wp_register_script('greenpay-checkout-hydration-guard-fallback', '', array(), null, false);
		wp_enqueue_script('greenpay-checkout-hydration-guard-fallback');
		wp_add_inline_script(
			'greenpay-checkout-hydration-guard-fallback',
			"(function(){if(window.__greenpayHydrationGuardInstalled)return;window.__greenpayHydrationGuardInstalled=true;window.addEventListener('unhandledrejection',function(e){var r=e.reason;if(r&&typeof r==='object'&&(r.code==='rest_not_logged_in'||(r.data&&r.data.status===401)||(typeof r.message==='string'&&r.message.indexOf('not currently logged in')!==-1))){e.preventDefault();}});})();",
			'after'
		);
	}

	/**
	 * Enqueues scripts for the plugin for Elementor checkout.
	 */
	public static function enqueue_scripts_elementor()
	{
		if (self::is_elementor_checkout()) {
			WC_GreenPay_Checkout_Assets::apply_classic_assets();
		}
	}

	/**
	 * Conditional check if the checkout is within the Elementor plugin
	 */
	public static function is_elementor_checkout()
	{
		global $post;

		if (!did_action('elementor/loaded') || !$post) {
			return false;
		}

		$is_elementor = class_exists('\\Elementor\\Plugin') && \Elementor\Plugin::$instance->db->is_built_with_elementor($post->ID);

		if (!$is_elementor) {
			return false;
		}

		return shortcode_exists('woocommerce_checkout');
	}

	public static function woocommerce_gateway_woocommerce_block_support()
	{
		if (class_exists('Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType')) {
			require_once dirname(__FILE__) . '/includes/blocks/class-wc-payments-blocks.php';
			add_action('woocommerce_blocks_payment_method_type_registration', function (PaymentMethodRegistry $payment_method_registry) {
				$container = Automattic\WooCommerce\Blocks\Package::container();
				$container->register(
					WC_GreenPay_Gateway_Blocks_Support::class,
					function () {
						return new WC_GreenPay_Gateway_Blocks_Support();
					}
				);

				$payment_method_registry->register(
					$container->get(WC_GreenPay_Gateway_Blocks_Support::class)
				);
			});
		}
	}

	/**
	 * Plugin url.
	 *
	 * @return string
	 */
	public static function plugin_url()
	{
		return untrailingslashit(plugins_url('/', __FILE__));
	}

	/**
	 * Plugin url.
	 *
	 * @return string
	 */
	public static function plugin_abspath()
	{
		return trailingslashit(plugin_dir_path(__FILE__));
	}

	/**
	 * Displays an admin notice if WooCommerce is not active.
	 */
	public static function woocommerce_missing_notice()
	{
		echo '<div class="error"><p>' . esc_html__('GreenPay™ by Green.Money requires WooCommerce to be installed and active.', 'woocommerce-gateway-green-money') . '</p></div>';
	}
}

// Initialize the plugin
WC_GreenPay_Payments::init();
