<?php
/**
 * PeachPay Authorize.net Integration Class.
 *
 * @package PeachPay
 */

defined( 'PEACHPAY_ABSPATH' ) || exit;

/**
 * PeachPay Authorize.net Integration class.
 */
final class PeachPay_Authnet_Integration {

	use PeachPay_Payment_Integration;

	/**
	 * Should the extension load?
	 */
	public static function should_load() {
		return true;
	}

	/**
	 * Is the extension enabled?
	 *
	 * Returns true when the admin has toggled the Authorize.net enable switch on.
	 * Falls back to true when credentials are already configured so that existing
	 * merchants are not silently disabled after a plugin update.
	 *
	 * NOTE: called before includes(), so PeachPay_Authnet_Credentials may not yet
	 * be loaded — use get_option() directly for the backward-compat check.
	 */
	public static function enabled() {
		$enabled_option = get_option( 'peachpay_authnet_enabled', null );

		if ( null !== $enabled_option ) {
			return filter_var( $enabled_option, FILTER_VALIDATE_BOOLEAN );
		}

		// Backward-compatibility: treat as enabled if credentials already exist in DB.
		return get_option( 'peachpay_authnet_credentials_test', false ) !== false
			|| get_option( 'peachpay_authnet_credentials_live', false ) !== false;
	}

	/**
	 * Called upon the integration being constructed and should_load returns true.
	 *
	 * @param boolean $enabled If the extension is enabled.
	 */
	private function includes( $enabled ) {
		require_once PEACHPAY_ABSPATH . 'core/payments/class-peachpay-payment.php';
		require_once PEACHPAY_ABSPATH . 'core/payments/authnet/class-peachpay-authnet-credentials.php';
		require_once PEACHPAY_ABSPATH . 'core/payments/authnet/hooks.php';
		require_once PEACHPAY_ABSPATH . 'core/payments/authnet/functions.php';
		require_once PEACHPAY_ABSPATH . 'core/payments/authnet/routes/authnet-webhook.php';

		if ( is_admin() ) {
			add_action(
				'peachpay_admin_add_payment_setting_section',
				function () {
					$class = 'pp-header pp-sub-nav-authnet no-border-bottom';

					add_settings_field(
						'peachpay_authnet_setting',
						null,
						function () {
							require PEACHPAY_ABSPATH . '/core/payments/authnet/admin/views/html-authnet-payment-page.php';
						},
						'peachpay',
						'peachpay_payment_settings_section',
						array( 'class' => $class )
					);
				}
			);
		}
	}

	/**
	 * Called on the WordPress init action.
	 *
	 * @param boolean $enabled If the extension is enabled.
	 */
	private function init( $enabled ) {
		if ( get_option( 'peachpay_connected_authnet_account' ) && ! PeachPay_Authnet_Credentials::is_configured() ) {
			add_action( 'admin_notices', array( __CLASS__, 'migration_notice' ) );
		}
	}

	/**
	 * Displays an admin notice prompting merchants to re-enter Authorize.net credentials
	 * after the migration away from the proxy-based OAuth connection.
	 */
	public static function migration_notice() {
		echo '<div class="notice notice-warning is-dismissible"><p>' .
			esc_html__( 'Your Authorize.net account credentials have been updated. Please re-enter your API Login ID and Transaction Key in the Authorize.net settings to continue accepting payments.', 'peachpay-for-woocommerce' ) .
			'</p></div>';
	}

	/**
	 * Called on the WordPress plugins loaded action.
	 *
	 * @param boolean $enabled If the extension is enabled.
	 */
	private function plugins_loaded( $enabled ) {
		include_once PEACHPAY_ABSPATH . '/core/payments/authnet/admin/tabs/class-peachpay-authnet-advanced.php';

		if ( is_admin() ) {
			PeachPay_Admin_Section::Create(
				'authnet',
				array(
					new PeachPay_Authnet_Advanced(),
				),
				array(
					array(
						'name' => __( 'Payments', 'peachpay-for-woocommerce' ),
						'url'  => PeachPay_Admin::admin_settings_url( 'peachpay', 'payment', '', '#authnet', false ),
					),
				)
			);
		}
	}

	/**
	 * Called on the woocommerce_init action.
	 *
	 * @param boolean $enabled If the extension is enabled.
	 */
	private function woocommerce_init( $enabled ) {
		require_once PEACHPAY_ABSPATH . '/core/payments/authnet/abstract/class-peachpay-authnet-payment-gateway.php';

		require_once PEACHPAY_ABSPATH . '/core/payments/authnet/utils/class-peachpay-authnet-rest-client.php';
		require_once PEACHPAY_ABSPATH . '/core/payments/authnet/utils/class-peachpay-authnet.php';
		require_once PEACHPAY_ABSPATH . '/core/payments/authnet/utils/class-peachpay-authnet-order-data.php';

		require_once PEACHPAY_ABSPATH . '/core/payments/authnet/gateways/class-peachpay-authnet-card-gateway.php';
		require_once PEACHPAY_ABSPATH . '/core/payments/authnet/gateways/class-peachpay-authnet-echeck-gateway.php';

		$this->payment_gateways[] = 'PeachPay_Authnet_Card_Gateway';
		// Temporarily disabled while Authorize.net eCheck checkout failures are investigated.
		// $this->payment_gateways[] = 'PeachPay_Authnet_ECheck_Gateway';

		peachpay_authnet_sync_gateway_enabled_state();
	}

	/**
	 * Called when WooCommerce Blocks are loaded.
	 */
	protected function woocommerce_blocks_loaded() {
		// Ensure the card gateway class is available when Blocks initializes payment methods.
		// WooCommerce Blocks can load before woocommerce_init where gateways are normally required.
		if ( ! class_exists( 'PeachPay_Authnet_Card_Gateway', false ) ) {
			require_once PEACHPAY_ABSPATH . '/core/payments/authnet/abstract/class-peachpay-authnet-payment-gateway.php';
			require_once PEACHPAY_ABSPATH . '/core/payments/authnet/utils/class-peachpay-authnet-rest-client.php';
			require_once PEACHPAY_ABSPATH . '/core/payments/authnet/utils/class-peachpay-authnet.php';
			require_once PEACHPAY_ABSPATH . '/core/payments/authnet/utils/class-peachpay-authnet-order-data.php';
			require_once PEACHPAY_ABSPATH . '/core/payments/authnet/gateways/class-peachpay-authnet-card-gateway.php';
		}

		require_once PEACHPAY_ABSPATH . 'core/payments/authnet/blocks/class-peachpay-authnet-card-gateway-blocks-support.php';

		add_action(
			'woocommerce_blocks_payment_method_type_registration',
			function ( Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry ) {
				$payment_method_registry->register( new PeachPay_Authnet_Card_Gateway_Blocks_Support() );
			}
		);
	}

	/**
	 * Determines whether Authorize.net credentials are configured.
	 *
	 * @param string|null $mode Optional mode override ('test' or 'live').
	 */
	public static function connected( $mode = null ) {
		return PeachPay_Authnet_Credentials::is_configured( $mode );
	}

	/**
	 * Gets Authorize.net public client key for Accept.js.
	 *
	 * @param string|null $mode Optional mode override ('test' or 'live').
	 */
	public static function public_client_key( $mode = null ) {
		return PeachPay_Authnet_Credentials::get_public_client_key( $mode );
	}

	/**
	 * Gets Authorize.net API Login ID for Accept.js.
	 *
	 * @param string|null $mode Optional mode override ('test' or 'live').
	 */
	public static function login_id( $mode = null ) {
		return PeachPay_Authnet_Credentials::get_login_id( $mode );
	}

	/**
	 * Gets Authorize.net supported currencies.
	 *
	 * Authorize.net supports all currencies configured on the merchant account.
	 * Returning null means no currency restriction is enforced.
	 */
	public static function supported_currencies() {
		return null;
	}

	/**
	 * Gets the PeachPay Authorize.net test or live mode status
	 *
	 * @param boolean|null $mode If the mode should override the global test mode. If not null a truthy value will indicate live mode where a falsy value will indicate test mode.
	 */
	public static function mode( $mode = 'detect' ) {
		if ( 'detect' === $mode ) {
			return ( peachpay_is_test_mode() || peachpay_is_local_development_site() || peachpay_is_staging_site() ) ? 'test' : 'live';
		}

		if ( 'live' === $mode ) {
			return 'live';
		} else {
			return 'test';
		}
	}

	/**
	 * Used to detect if a gateway is a PeachPay Authorize.net gateway.
	 *
	 * @param string $gateway_id Payment gateway id.
	 */
	public static function is_payment_gateway( $gateway_id ) {
		return peachpay_starts_with( $gateway_id, 'peachpay_authnet_' );
	}

	/**
	 * Authorize.net rest api endpoints.
	 *
	 * @param boolean $enabled If the extension is enabled.
	 */
	private function rest_api_init( $enabled ) {
		register_rest_route(
			PEACHPAY_ROUTE_BASE,
			'/authnet/webhook',
			array(
				'methods'             => 'POST',
				'callback'            => 'peachpay_rest_api_authnet_webhook',
				'permission_callback' => '__return_true',
			)
		);
	}
}
PeachPay_Authnet_Integration::instance();
