<?php
/**
 * WPForms Square Hosted Checkout integration.
 *
 * @package SHC4WC
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class SHC4WC_WPForms {
	const GATEWAY_SLUG = 'payments_square_connect';
	const FIELD_TYPE   = 'shc4wc-square';

	/** @var self|null */
	private static $instance = null;

	/** @var array */
	private $builder_form_data = array();

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

	private function __construct() {
		add_action( 'init', array( $this, 'load_field' ), 20 );

		add_filter( 'wpforms_payments_available', array( $this, 'register_payment' ) );
		add_action( 'wpforms_builder_enqueues', array( $this, 'builder_enqueues' ) );
		add_filter( 'wpforms_builder_strings', array( $this, 'builder_strings' ) );
		add_action( 'wpforms_payments_panel_sidebar', array( $this, 'builder_sidebar' ), 5 );
		add_action( 'wpforms_payments_panel_content', array( $this, 'builder_output' ), 5 );
		add_filter( 'wpforms_has_payment_gateway', array( $this, 'has_payment_gateway' ), 10, 2 );
		add_action( 'wpforms_process', array( $this, 'maybe_start_payment' ), 5, 3 );
		add_action( 'wpforms_frontend_output_form_before', array( $this, 'maybe_output_success_notice' ), 5, 2 );
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_success_styles' ), 20 );
	}

	/**
	 * Load the hosted checkout field type.
	 */
	public function load_field() {
		if ( ! class_exists( 'WPForms_Field' ) ) {
			return;
		}

		require_once SHC4WC_PLUGIN_DIR . 'includes/class-shc4wc-wpforms-field.php';
		new SHC4WC_WPForms_Field();
	}

	/**
	 * @param array $payments_available Available gateways.
	 * @return array
	 */
	public function register_payment( $payments_available ) {
		$payments_available                      = (array) $payments_available;
		$payments_available[ self::GATEWAY_SLUG ] = __( 'Payments Square Connect', 'payments-connect-square' );
		return $payments_available;
	}

	/**
	 * Enqueue WPForms builder scripts.
	 */
	public function builder_enqueues() {
		wp_enqueue_script(
			'shc4wc-wpforms-builder',
			SHC4WC_PLUGIN_URL . 'assets/js/wpforms-builder.js',
			array( 'jquery', 'wpforms-builder' ),
			SHC4WC_VERSION,
			true
		);

		wp_localize_script(
			'shc4wc-wpforms-builder',
			'shc4wc_wpforms_builder',
			array(
				'isConnected' => SHC4WC_Plugin::is_connected(),
				'connectUrl'  => admin_url( 'admin.php?page=payments-square-connect' ),
				'gatewaySlug' => self::GATEWAY_SLUG,
				'fieldType'   => self::FIELD_TYPE,
			)
		);
	}

	/**
	 * Localized strings for the WPForms builder modal.
	 *
	 * @param array $strings Builder JS strings.
	 * @return array
	 */
	public function builder_strings( $strings ) {
		$strings = (array) $strings;

		$strings['shc4wc_square_connection_required'] = '<p>' . esc_html__(
			'Square account connection is required when using the Square field. Connect your Square account to start accepting payments.',
			'payments-connect-square'
		) . '</p>';

		$strings['shc4wc_square_connect_button'] = esc_html__( 'Connect With Square', 'payments-connect-square' );

		return $strings;
	}

	/**
	 * Payments panel sidebar tile.
	 */
	public function builder_sidebar() {
		if ( ! function_exists( 'wpforms_render' ) ) {
			return;
		}

		echo wpforms_render( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			'builder/payment/sidebar',
			array(
				'configured'  => $this->is_builder_configured() ? 'configured' : '',
				'slug'        => self::GATEWAY_SLUG,
				'icon'        => self::get_sidebar_icon_url(),
				'name'        => __( 'Payments Square Connect', 'payments-connect-square' ),
				'recommended' => false,
			),
			true
		);
	}

	/**
	 * WPForms payments sidebar icon (same Square mark as native WPForms Square).
	 *
	 * @return string
	 */
	private static function get_sidebar_icon_url() {
		if ( defined( 'WPFORMS_PLUGIN_DIR' ) && defined( 'WPFORMS_PLUGIN_URL' ) ) {
			$wpforms_icon = WPFORMS_PLUGIN_DIR . 'assets/images/addon-icon-square.png';
			if ( file_exists( $wpforms_icon ) ) {
				return WPFORMS_PLUGIN_URL . 'assets/images/addon-icon-square.png';
			}
		}

		return SHC4WC_PLUGIN_URL . 'assets/images/addon-icon-square.png';
	}

	/**
	 * Payments panel settings.
	 */
	public function builder_output() {
		if ( ! function_exists( 'wpforms_panel_field' ) ) {
			return;
		}

		$form_data    = $this->get_builder_form_data();
		$connected    = SHC4WC_Plugin::is_connected();
		$settings_url = admin_url( 'admin.php?page=payments-square-connect' );
		?>
		<div class="wpforms-panel-content-section wpforms-panel-content-section-<?php echo esc_attr( self::GATEWAY_SLUG ); ?>"
			id="<?php echo esc_attr( self::GATEWAY_SLUG ); ?>-provider"
			data-provider="<?php echo esc_attr( self::GATEWAY_SLUG ); ?>"
			data-provider-name="<?php echo esc_attr__( 'Payments Square Connect', 'payments-connect-square' ); ?>">

			<div class="wpforms-panel-content-section-title">
				<?php esc_html_e( 'Payments Square Connect', 'payments-connect-square' ); ?>
			</div>

			<div class="wpforms-payment-settings wpforms-clear">
				<?php if ( ! $connected ) : ?>
					<?php $this->render_builder_disconnected_alert( $settings_url ); ?>
				<?php else : ?>
					<p class="description">
						<?php esc_html_e( 'Uses your existing Payments Square Connect account. Add a Single Item payment field for the amount and a Square Hosted Checkout field to the form.', 'payments-connect-square' ); ?>
					</p>

					<div id="wpforms-panel-content-section-payment-<?php echo esc_attr( self::GATEWAY_SLUG ); ?>">
						<div class="wpforms-panel-content-section-payment">
							<h2 class="wpforms-panel-content-section-payment-subtitle">
								<?php esc_html_e( 'One-Time Payments', 'payments-connect-square' ); ?>
							</h2>
							<?php
							wpforms_panel_field(
								'toggle',
								self::GATEWAY_SLUG,
								'enable_one_time',
								$form_data,
								esc_html__( 'Enable one-time payments', 'payments-connect-square' ),
								array(
									'parent'  => 'payments',
									'default' => '0',
									'class'   => 'wpforms-panel-content-section-payment-toggle wpforms-panel-content-section-payment-toggle-one-time',
								)
							);
							?>
							<div class="wpforms-panel-content-section-payment-one-time wpforms-panel-content-section-payment-toggled-body"></div>
						</div>

						<div class="wpforms-panel-content-section-payment">
							<h2 class="wpforms-panel-content-section-payment-subtitle">
								<?php esc_html_e( 'Subscriptions', 'payments-connect-square' ); ?>
							</h2>
							<?php
							wpforms_panel_field(
								'toggle',
								self::GATEWAY_SLUG,
								'enable_recurring',
								$form_data,
								esc_html__( 'Enable subscription signup', 'payments-connect-square' ),
								array(
									'parent'  => 'payments',
									'default' => '0',
									'class'   => 'wpforms-panel-content-section-payment-toggle wpforms-panel-content-section-payment-toggle-recurring',
								)
							);
							?>
							<div class="wpforms-panel-content-section-payment-recurring wpforms-panel-content-section-payment-toggled-body">
								<?php
								wpforms_panel_field(
									'text',
									self::GATEWAY_SLUG,
									'plan_variation_id',
									$form_data,
									esc_html__( 'Square plan variation ID', 'payments-connect-square' ),
									array(
										'parent'  => 'payments',
										'tooltip' => esc_html__( 'Copy from Payments Square Connect → Subscription Plans.', 'payments-connect-square' ),
									)
								);
								wpforms_panel_field(
									'text',
									self::GATEWAY_SLUG,
									'subscription_name',
									$form_data,
									esc_html__( 'Checkout label (optional)', 'payments-connect-square' ),
									array( 'parent' => 'payments' )
								);
								wpforms_panel_field(
									'text',
									self::GATEWAY_SLUG,
									'subscription_amount',
									$form_data,
									esc_html__( 'Amount (optional)', 'payments-connect-square' ),
									array(
										'parent'  => 'payments',
										'tooltip' => esc_html__( 'Leave empty to use the price from Square.', 'payments-connect-square' ),
									)
								);
								?>
							</div>
						</div>
					</div>
				<?php endif; ?>
			</div>
		</div>
		<?php
	}

	/**
	 * Disconnected-state alert in the WPForms builder (matches native Square panel).
	 *
	 * @param string $settings_url Connect settings admin URL.
	 */
	private function render_builder_disconnected_alert( $settings_url ) {
		$icon_url = self::get_sidebar_icon_url();
		?>
		<img src="<?php echo esc_url( $icon_url ); ?>" class="wpforms-builder-payment-settings-alert-icon" alt="<?php esc_attr_e( 'Square', 'payments-connect-square' ); ?>">
		<div class="wpforms-builder-payment-settings-default-content">
			<p><?php esc_html_e( 'Connect to your Square account and start accepting payments today.', 'payments-connect-square' ); ?></p>
			<a href="<?php echo esc_url( $settings_url ); ?>" class="wpforms-btn wpforms-btn-md wpforms-btn-orange wpforms-payments-connect-btn">
				<?php esc_html_e( 'Connect With Square', 'payments-connect-square' ); ?>
			</a>
		</div>
		<?php
	}

	/**
	 * @param bool  $result    Initial value.
	 * @param array $form_data Form data.
	 * @return bool
	 */
	public function has_payment_gateway( $result, $form_data ) {
		if ( self::is_payments_enabled( $form_data ) ) {
			return true;
		}
		return (bool) $result;
	}

	/**
	 * Intercept submission and redirect to Square Hosted Checkout.
	 *
	 * @param array $fields    Form fields.
	 * @param array $entry     Raw submission.
	 * @param array $form_data Form data.
	 */
	public function maybe_start_payment( $fields, $entry, $form_data ) {
		$form_id = isset( $form_data['id'] ) ? (int) $form_data['id'] : 0;
		if ( $form_id <= 0 || ! self::form_has_hosted_field( $form_data ) ) {
			return;
		}

		$process = wpforms()->obj( 'process' );
		if ( ! $process || ! empty( $process->errors[ $form_id ] ) ) {
			return;
		}

		if ( ! self::is_payments_enabled( $form_data ) ) {
			$process->errors[ $form_id ]['footer'] = esc_html__(
				'Enable one-time or subscription payments under Payments → Payments Square Connect in the form builder.',
				'payments-connect-square'
			);
			return;
		}

		if ( ! SHC4WC_Plugin::is_connected() ) {
			$process->errors[ $form_id ]['footer'] = esc_html__( 'Square is not connected. Ask the site administrator to connect under Payments Square Connect.', 'payments-connect-square' );
			return;
		}

		$settings    = SHC4WC_Plugin::get_settings();
		$location_id = isset( $settings['location_id'] ) ? trim( (string) $settings['location_id'] ) : '';
		if ( '' === $location_id ) {
			$process->errors[ $form_id ]['footer'] = esc_html__( 'Square location is not configured.', 'payments-connect-square' );
			return;
		}

		$is_sub   = self::is_recurring_enabled( $form_data );
		$amount   = self::resolve_amount( $fields, $form_data, $is_sub );
		$currency = self::get_currency();
		$ref      = 'wpforms_' . wp_generate_password( 16, false, false );
		$key      = wp_hash( $ref . wp_salt( 'auth' ) );
		$api      = new SHC4WC_API( $settings );
		$customer = self::extract_buyer_from_fields( $fields );

		if ( $is_sub ) {
			$config = self::resolve_subscription_config( $form_data );
			if ( '' === $config['variation_id'] || $config['amount'] <= 0 ) {
				$process->errors[ $form_id ]['footer'] = esc_html__( 'Square subscription plan is not configured for this form.', 'payments-connect-square' );
				return;
			}
			$amount   = (float) $config['amount'];
			$response = $api->create_subscription_payment_link(
				$config['amount'],
				$currency,
				$ref,
				$config['variation_id'],
				array(
					'description' => sprintf(
						/* translators: 1: form title, 2: reference id. */
						__( 'WPForms subscription: %1$s (%2$s)', 'payments-connect-square' ),
						self::get_form_title( $form_data ),
						$ref
					),
					'return_args' => array(
						'type' => 'wpforms',
						'ref'  => $ref,
						'key'  => $key,
					),
					'line_name'   => $config['name'] ? $config['name'] : self::get_form_title( $form_data ),
					'customer'    => $customer,
				)
			);
		} else {
			if ( $amount <= 0 ) {
				$process->errors[ $form_id ]['footer'] = esc_html__( 'Enter a valid payment amount.', 'payments-connect-square' );
				return;
			}

			$response = $api->create_payment_link(
				$amount,
				$currency,
				$ref,
				array(
					'description' => sprintf(
						/* translators: 1: form title, 2: reference id. */
						__( 'WPForms: %1$s (%2$s)', 'payments-connect-square' ),
						self::get_form_title( $form_data ),
						$ref
					),
					'return_args' => array(
						'type' => 'wpforms',
						'ref'  => $ref,
						'key'  => $key,
					),
					'line_name'   => self::get_form_title( $form_data ),
					'customer'    => $customer,
				)
			);
		}

		if ( is_wp_error( $response ) ) {
			$api->log( 'WPForms create payment link failed', array( 'error' => $response->get_error_data() ), 'error' );
			$process->errors[ $form_id ]['footer'] = esc_html__( 'Could not start Square payment. Please try again.', 'payments-connect-square' );
			return;
		}

		$link = isset( $response['payment_link']['url'] ) ? esc_url_raw( $response['payment_link']['url'] ) : '';
		if ( '' === $link ) {
			$process->errors[ $form_id ]['footer'] = esc_html__( 'Invalid response from Square.', 'payments-connect-square' );
			return;
		}

		set_transient(
			'shc4wc_wpforms_' . $ref,
			array(
				'form_id'         => $form_id,
				'fields'          => $fields,
				'entry'           => $entry,
				'form_data'       => $form_data,
				'amount'          => $amount,
				'currency'        => $currency,
				'is_subscription' => $is_sub,
				'ref'             => $ref,
				'link_id'         => isset( $response['payment_link']['id'] ) ? (string) $response['payment_link']['id'] : '',
				'square_order_id' => self::extract_square_order_id( $response ),
				'return_url'      => self::get_submission_return_url(),
			),
			DAY_IN_SECONDS
		);

		wp_redirect( esc_url_raw( $link ) ); // phpcs:ignore WordPress.Security.SafeRedirect.wp_redirect_wp_redirect -- Square Hosted Checkout.
		exit;
	}

	/**
	 * Handle buyer return from Square.
	 *
	 * @param string $ref Reference id.
	 * @param string $key Verification key.
	 */
	public static function handle_return( $ref, $key ) {
		$ref = sanitize_text_field( (string) $ref );
		$key = sanitize_text_field( (string) $key );

		if ( '' === $ref || '' === $key || ! hash_equals( wp_hash( $ref . wp_salt( 'auth' ) ), $key ) ) {
			wp_safe_redirect( home_url( '/' ) );
			exit;
		}

		$stored = get_transient( 'shc4wc_wpforms_' . $ref );
		if ( ! is_array( $stored ) ) {
			wp_safe_redirect( home_url( '/' ) );
			exit;
		}

		self::complete_deferred_submission( $stored );
		delete_transient( 'shc4wc_wpforms_' . $ref );

		$url = ! empty( $stored['return_url'] ) ? (string) $stored['return_url'] : home_url( '/' );
		if ( ! empty( $stored['is_subscription'] ) ) {
			$url = add_query_arg( 'shc4wc_wpforms_subscribed', '1', $url );
		}
		$url = add_query_arg( 'shc4wc_wpforms_paid', '1', $url );

		wp_safe_redirect( $url );
		exit;
	}

	/**
	 * Thank-you banner after Square redirect.
	 *
	 * @param array   $form_data Form data.
	 * @param WP_Post $form      Form post.
	 */
	public function maybe_output_success_notice( $form_data, $form ) {
		unset( $form );
		if ( empty( $_GET['shc4wc_wpforms_paid'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			return;
		}
		if ( ! is_array( $form_data ) || ! self::form_has_hosted_field( $form_data ) ) {
			return;
		}

		$message = ! empty( $_GET['shc4wc_wpforms_subscribed'] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			? esc_html__( 'Thank you — your Square subscription was started and your form was submitted.', 'payments-connect-square' )
			: esc_html__( 'Thank you — your Square payment was received and your form was submitted.', 'payments-connect-square' );

		printf(
			'<div class="shc4wc-wpforms-payment-success" role="status">%s</div>',
			esc_html( $message )
		);
	}

	/**
	 * Success banner styles.
	 */
	public function enqueue_success_styles() {
		if ( empty( $_GET['shc4wc_wpforms_paid'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			return;
		}

		$css = '.shc4wc-wpforms-payment-success{display:block;margin:0 0 1.5em;padding:1em 1.25em;border:2px solid #46b450;background:#ecf7ed;color:#1e4620;border-radius:4px;}';
		wp_register_style( 'shc4wc-wpforms-payment-success', false, array(), SHC4WC_VERSION );
		wp_enqueue_style( 'shc4wc-wpforms-payment-success' );
		wp_add_inline_style( 'shc4wc-wpforms-payment-success', $css );
	}

	/**
	 * Whether the form includes our hosted checkout field.
	 *
	 * @param array $form_data Form data.
	 * @return bool
	 */
	public static function form_has_hosted_field( $form_data ) {
		if ( empty( $form_data['fields'] ) || ! is_array( $form_data['fields'] ) ) {
			return false;
		}
		foreach ( $form_data['fields'] as $field ) {
			if ( is_array( $field ) && isset( $field['type'] ) && self::FIELD_TYPE === $field['type'] ) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @param array $form_data Form data.
	 * @return bool
	 */
	public static function is_payments_enabled( $form_data ) {
		return self::is_one_time_enabled( $form_data ) || self::is_recurring_enabled( $form_data );
	}

	/**
	 * @param array $form_data Form data.
	 * @return bool
	 */
	public static function is_one_time_enabled( $form_data ) {
		return ! empty( $form_data['payments'][ self::GATEWAY_SLUG ]['enable_one_time'] );
	}

	/**
	 * @param array $form_data Form data.
	 * @return bool
	 */
	public static function is_recurring_enabled( $form_data ) {
		return ! empty( $form_data['payments'][ self::GATEWAY_SLUG ]['enable_recurring'] );
	}

	/**
	 * @param array $fields    Form fields.
	 * @param array $form_data Form data.
	 * @param bool  $is_sub    Subscription mode.
	 * @return float
	 */
	private static function resolve_amount( $fields, $form_data, $is_sub ) {
		if ( $is_sub ) {
			$config = self::resolve_subscription_config( $form_data );
			return (float) $config['amount'];
		}
		if ( ! function_exists( 'wpforms_get_total_payment' ) ) {
			return 0.0;
		}
		return (float) wpforms_get_total_payment( $fields );
	}

	/**
	 * @param array $form_data Form data.
	 * @return array{variation_id:string,amount:float,name:string}
	 */
	private static function resolve_subscription_config( $form_data ) {
		$config = array(
			'variation_id' => '',
			'amount'         => 0.0,
			'name'           => '',
		);

		$payments = isset( $form_data['payments'][ self::GATEWAY_SLUG ] ) && is_array( $form_data['payments'][ self::GATEWAY_SLUG ] )
			? $form_data['payments'][ self::GATEWAY_SLUG ]
			: array();

		if ( ! empty( $payments['plan_variation_id'] ) ) {
			$config['variation_id'] = sanitize_text_field( (string) $payments['plan_variation_id'] );
		}
		if ( ! empty( $payments['subscription_name'] ) ) {
			$config['name'] = sanitize_text_field( (string) $payments['subscription_name'] );
		}
		if ( ! empty( $payments['subscription_amount'] ) ) {
			$config['amount'] = (float) $payments['subscription_amount'];
		}

		if ( $config['amount'] <= 0 && '' !== $config['variation_id'] ) {
			$catalog = SHC4WC_Subscriptions::find_variation_by_id( $config['variation_id'] );
			if ( $catalog ) {
				$config['amount'] = (float) $catalog['amount'];
				if ( '' === $config['name'] ) {
					$config['name'] = (string) $catalog['name'];
				}
			}
		}

		return $config;
	}

	/**
	 * @param array $stored Pending submission payload.
	 */
	private static function complete_deferred_submission( array $stored ) {
		if ( ! function_exists( 'wpforms' ) ) {
			return;
		}

		$fields    = isset( $stored['fields'] ) && is_array( $stored['fields'] ) ? $stored['fields'] : array();
		$entry     = isset( $stored['entry'] ) && is_array( $stored['entry'] ) ? $stored['entry'] : array();
		$form_data = isset( $stored['form_data'] ) && is_array( $stored['form_data'] ) ? $stored['form_data'] : array();
		$form_id   = isset( $stored['form_id'] ) ? (int) $stored['form_id'] : 0;

		if ( $form_id <= 0 || empty( $fields ) ) {
			return;
		}

		$process = wpforms()->obj( 'process' );
		if ( ! $process ) {
			return;
		}

		$process->form_data = $form_data;
		$process->fields    = $fields;
		$process->entry_email( $fields, $entry, $form_data, 0, 'entry' );

		if ( function_exists( 'wpforms_has_payment' ) && wpforms_has_payment( 'entry', $fields ) && wpforms()->obj( 'submission' ) && wpforms()->obj( 'payment' ) ) {
			$entry['entry_id'] = 0;
			$submission        = wpforms()->obj( 'submission' )->register( $fields, $entry, $form_id, $form_data );
			$payment_data      = $submission->prepare_payment_data();
			if ( ! empty( $payment_data ) ) {
				$plugin_settings = SHC4WC_Plugin::get_settings();
				$location_id     = isset( $plugin_settings['location_id'] ) ? trim( (string) $plugin_settings['location_id'] ) : '';
				$square_order_id = ! empty( $stored['square_order_id'] ) ? sanitize_text_field( (string) $stored['square_order_id'] ) : '';
				$payment_link_id = ! empty( $stored['link_id'] ) ? sanitize_text_field( (string) $stored['link_id'] ) : '';
				$square_payment_id = '';

				if ( '' !== $square_order_id ) {
					$square_payment_id = SHC4WC_Plugin::instance()->retrieve_square_payment_id_for_hosted_checkout(
						$square_order_id,
						$payment_link_id,
						$location_id,
						time()
					);
				}

				$payment_data['gateway']        = 'payments-square-connect';
				$payment_data['status']         = 'processed';
				$payment_data['transaction_id'] = '' !== $square_payment_id
					? $square_payment_id
					: ( isset( $stored['ref'] ) ? sanitize_text_field( (string) $stored['ref'] ) : '' );
				$payment_data['mode']           = ( isset( $plugin_settings['environment'] ) && 'live' === $plugin_settings['environment'] ) ? 'live' : 'test';
				$payment_data['title']          = self::get_form_title( $form_data );

				$new_payment_id = wpforms()->obj( 'payment' )->add( $payment_data );
				if ( $new_payment_id && wpforms()->obj( 'payment_meta' ) ) {
					if ( ! empty( $stored['ref'] ) ) {
						wpforms()->obj( 'payment_meta' )->add( $new_payment_id, 'shc4wc_reference_id', sanitize_text_field( (string) $stored['ref'] ) );
					}
					if ( '' !== $square_order_id ) {
						wpforms()->obj( 'payment_meta' )->add( $new_payment_id, 'shc4wc_square_order_id', $square_order_id );
					}
					if ( '' !== $payment_link_id ) {
						wpforms()->obj( 'payment_meta' )->add( $new_payment_id, 'shc4wc_payment_link_id', $payment_link_id );
					}
				}
			}
		}

		/**
		 * Fires after a WPForms submission is completed following Square Hosted Checkout.
		 *
		 * @param array $fields    Form fields.
		 * @param array $entry     Raw submission.
		 * @param array $form_data Form data.
		 */
		do_action( 'shc4wc_wpforms_payment_complete', $fields, $entry, $form_data );
	}

	/**
	 * @return string
	 */
	private static function get_currency() {
		if ( function_exists( 'wpforms_get_currency' ) ) {
			return wpforms_get_currency();
		}
		if ( function_exists( 'get_woocommerce_currency' ) ) {
			return get_woocommerce_currency();
		}
		$locations = SHC4WC_Plugin::get_locations();
		if ( ! empty( $locations[0]['currency'] ) ) {
			return strtoupper( (string) $locations[0]['currency'] );
		}
		return 'USD';
	}

	/**
	 * @return string
	 */
	private static function get_submission_return_url() {
		// phpcs:disable WordPress.Security.NonceVerification.Missing
		if ( ! empty( $_POST['page_url'] ) ) {
			return esc_url_raw( wp_unslash( (string) $_POST['page_url'] ) );
		}
		$page_id = ! empty( $_POST['page_id'] ) ? absint( $_POST['page_id'] ) : 0;
		// phpcs:enable WordPress.Security.NonceVerification.Missing
		if ( $page_id > 0 ) {
			$permalink = get_permalink( $page_id );
			if ( is_string( $permalink ) && '' !== $permalink ) {
				return $permalink;
			}
		}
		$referer = wp_get_referer();
		if ( is_string( $referer ) && '' !== $referer ) {
			return $referer;
		}
		return home_url( '/' );
	}

	/**
	 * @param array $form_data Form data.
	 * @return string
	 */
	private static function get_form_title( $form_data ) {
		if ( ! empty( $form_data['settings']['form_title'] ) ) {
			return sanitize_text_field( (string) $form_data['settings']['form_title'] );
		}
		return __( 'Form payment', 'payments-connect-square' );
	}

	/**
	 * Pull buyer email / name / phone from WPForms submitted fields.
	 *
	 * @param array $fields Processed field values.
	 * @return array{email:string,given_name:string,family_name:string,phone:string,wp_user_id:int}
	 */
	private static function extract_buyer_from_fields( $fields ) {
		$buyer = array(
			'email'       => '',
			'given_name'  => '',
			'family_name' => '',
			'phone'       => '',
			'wp_user_id'  => get_current_user_id(),
		);

		if ( ! is_array( $fields ) ) {
			return $buyer;
		}

		foreach ( $fields as $field ) {
			if ( ! is_array( $field ) || empty( $field['type'] ) ) {
				continue;
			}
			$type  = (string) $field['type'];
			$value = isset( $field['value'] ) ? $field['value'] : '';

			if ( 'email' === $type && '' === $buyer['email'] ) {
				$email = is_array( $value ) ? ( isset( $value['primary'] ) ? $value['primary'] : reset( $value ) ) : $value;
				$email = sanitize_email( (string) $email );
				if ( is_email( $email ) ) {
					$buyer['email'] = $email;
				}
				continue;
			}

			if ( 'name' === $type && ( '' === $buyer['given_name'] || '' === $buyer['family_name'] ) ) {
				if ( is_array( $value ) ) {
					if ( ! empty( $value['first'] ) ) {
						$buyer['given_name'] = sanitize_text_field( (string) $value['first'] );
					}
					if ( ! empty( $value['last'] ) ) {
						$buyer['family_name'] = sanitize_text_field( (string) $value['last'] );
					}
				} elseif ( is_string( $value ) && '' !== trim( $value ) ) {
					$parts = preg_split( '/\s+/', trim( $value ), 2 );
					if ( ! empty( $parts[0] ) ) {
						$buyer['given_name'] = sanitize_text_field( $parts[0] );
					}
					if ( ! empty( $parts[1] ) ) {
						$buyer['family_name'] = sanitize_text_field( $parts[1] );
					}
				}
				continue;
			}

			if ( in_array( $type, array( 'phone', 'tel' ), true ) && '' === $buyer['phone'] && is_string( $value ) && '' !== trim( $value ) ) {
				$buyer['phone'] = sanitize_text_field( $value );
			}
		}

		if ( '' === $buyer['email'] && is_user_logged_in() ) {
			$user = wp_get_current_user();
			if ( $user && is_email( $user->user_email ) ) {
				$buyer['email'] = sanitize_email( $user->user_email );
				if ( '' === $buyer['given_name'] && $user->first_name ) {
					$buyer['given_name'] = sanitize_text_field( (string) $user->first_name );
				}
				if ( '' === $buyer['family_name'] && $user->last_name ) {
					$buyer['family_name'] = sanitize_text_field( (string) $user->last_name );
				}
			}
		}

		return $buyer;
	}

	/**
	 * @param array $response Square API response.
	 * @return string
	 */
	private static function extract_square_order_id( array $response ) {
		if ( ! empty( $response['related_resources']['orders'][0]['id'] ) ) {
			return sanitize_text_field( (string) $response['related_resources']['orders'][0]['id'] );
		}
		if ( ! empty( $response['payment_link']['order_id'] ) ) {
			return sanitize_text_field( (string) $response['payment_link']['order_id'] );
		}
		return '';
	}

	/**
	 * @return array
	 */
	private function get_builder_form_data() {
		if ( ! empty( $this->builder_form_data ) ) {
			return $this->builder_form_data;
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$form_id = isset( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : 0;
		if ( $form_id && function_exists( 'wpforms' ) && wpforms()->obj( 'form' ) ) {
			$this->builder_form_data = (array) wpforms()->obj( 'form' )->get(
				$form_id,
				array( 'content_only' => true )
			);
		}

		return $this->builder_form_data;
	}

	/**
	 * @return bool
	 */
	private function is_builder_configured() {
		$form_data = $this->get_builder_form_data();
		return SHC4WC_Plugin::is_connected() && self::is_payments_enabled( $form_data ) && self::form_has_hosted_field( $form_data );
	}
}
