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

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

class SHC4WC_SureForms {

	const METHOD = 'payments_square_connect';

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

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

	private function __construct() {
		add_filter( 'srfm_payment_methods_registry', array( $this, 'register_payment_method' ) );
		add_filter( 'srfm_payment_history_supported_gateways', array( $this, 'register_history_gateway' ) );
		add_filter( 'srfm_verify_payment_value', array( $this, 'verify_payment_value' ), 10, 1 );
		add_filter( 'srfm_form_submit_data', array( $this, 'maybe_intercept_submit' ), 3, 1 );
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ), 20 );
		add_action( 'wp_footer', array( $this, 'maybe_render_success_notice' ), 20 );
	}

	/**
	 * @param array $methods Payment methods.
	 * @return array
	 */
	public function register_payment_method( $methods ) {
		if ( ! SHC4WC_Plugin::is_connected() ) {
			return $methods;
		}

		$methods[ self::METHOD ] = array(
			'id'              => self::METHOD,
			'label'           => __( 'Square Hosted Checkout', 'payments-connect-square' ),
			'description'     => __( 'Pay securely on Square\'s hosted page', 'payments-connect-square' ),
			'icon'            => 'money-bill',
			'enabled'         => true,
			'container_class' => 'shc4wc-sureforms-payment',
		);

		return $methods;
	}

	/**
	 * @param array $gateways Gateways.
	 * @return array
	 */
	public function register_history_gateway( $gateways ) {
		$gateways[] = self::METHOD;
		return array_values( array_unique( array_map( 'sanitize_text_field', $gateways ) ) );
	}

	/**
	 * @param array $context Verification context.
	 * @return array
	 */
	public function verify_payment_value( $context ) {
		if ( empty( $context['payment_value'] ) || ! is_array( $context['payment_value'] ) ) {
			return $context;
		}

		$payment_value = $context['payment_value'];
		if ( empty( $payment_value['paymentMethod'] ) || self::METHOD !== $payment_value['paymentMethod'] ) {
			return $context;
		}

		if ( empty( $payment_value['transactionId'] ) ) {
			return $context;
		}

		return array(
			'payment_id' => sanitize_text_field( (string) $payment_value['transactionId'] ),
		);
	}

	/**
	 * @param array $form_data Form submit data.
	 * @return array
	 */
	public function maybe_intercept_submit( $form_data ) {
		if ( empty( $form_data ) || ! is_array( $form_data ) ) {
			return $form_data;
		}

		if ( ! empty( $_GET['shc4wc_sureforms_paid'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			return $form_data;
		}

		$payment = self::find_payment_field( $form_data );
		if ( ! $payment ) {
			return $form_data;
		}

		$payment_value = $payment['value'];
		if ( empty( $payment_value['paymentMethod'] ) || self::METHOD !== $payment_value['paymentMethod'] ) {
			return $form_data;
		}

		if ( ! empty( $payment_value['transactionId'] ) ) {
			return $form_data;
		}

		$amount = self::resolve_amount( $payment_value, $form_data );
		if ( $amount <= 0 ) {
			return $form_data;
		}

		$form_id = isset( $form_data['form_id'] ) ? (int) $form_data['form_id'] : 0;
		$started = SHC4WC_Hosted_Checkout_Flow::start_one_time_payment(
			array(
				'type'        => 'sureforms',
				'amount'      => $amount,
				'currency'    => ! empty( $payment_value['currency'] ) ? (string) $payment_value['currency'] : SHC4WC_Hosted_Checkout_Flow::default_currency(),
				'description' => sprintf( __( 'SureForms payment (form %d)', 'payments-connect-square' ), $form_id ),
				'line_name'   => __( 'SureForms payment', 'payments-connect-square' ),
				'customer'    => self::extract_buyer( $form_data ),
				'payload'     => array(
					'form_data'   => $form_data,
					'payment_key' => $payment['key'],
					'block_id'    => (string) ( $payment_value['blockId'] ?? '' ),
					'return_url'  => self::resolve_return_url(),
				),
			)
		);

		if ( is_wp_error( $started ) ) {
			wp_send_json_error(
				array(
					'message' => $started->get_error_message(),
				)
			);
		}

		wp_send_json(
			array(
				'success'      => true,
				'message'      => esc_html__( 'Redirecting to Square…', 'payments-connect-square' ),
				'redirect_url' => $started['redirect'],
				'data'         => array(
					'after_submit' => false,
				),
			)
		);
	}

	/**
	 * @param string $ref Reference id.
	 * @param string $key Return key.
	 * @return void
	 */
	public static function handle_return( $ref, $key ) {
		$stored = SHC4WC_Hosted_Checkout_Flow::pull_pending( 'sureforms', $ref, $key );
		if ( ! is_array( $stored ) || empty( $stored['form_data'] ) || ! is_array( $stored['form_data'] ) ) {
			wp_safe_redirect( home_url( '/' ) );
			exit;
		}

		$form_data = $stored['form_data'];
		$payment   = self::find_payment_field( $form_data );
		if ( ! $payment ) {
			wp_safe_redirect( home_url( '/' ) );
			exit;
		}

		$square_payment_id = '';
		if ( class_exists( 'SHC4WC_Plugin' ) && ! empty( $stored['square_order_id'] ) ) {
			$square_payment_id = SHC4WC_Plugin::instance()->retrieve_square_payment_id_for_hosted_checkout(
				(string) $stored['square_order_id'],
				(string) ( $stored['link_id'] ?? '' ),
				'',
				time()
			);
		}

		$payment_value = $payment['value'];
		$payment_value['paymentMethod'] = self::METHOD;
		$payment_value['transactionId'] = $square_payment_id ? $square_payment_id : (string) $ref;
		$payment_value['status']        = 'succeeded';
		$form_data[ $payment['key'] ]   = wp_json_encode( $payment_value );

		$url = ! empty( $stored['return_url'] ) ? (string) $stored['return_url'] : home_url( '/' );

		if ( class_exists( '\SRFM\Inc\Form_Submit' ) ) {
			$response = \SRFM\Inc\Form_Submit::instance()->handle_form_entry( $form_data );
			if ( is_array( $response ) && ! empty( $response['redirect_url'] ) ) {
				$url = (string) $response['redirect_url'];
			}
		}

		$url = SHC4WC_Hosted_Checkout_Flow::add_paid_query_arg( $url, 'shc4wc_sureforms_paid' );
		wp_safe_redirect( $url );
		exit;
	}

	/**
	 * @return void
	 */
	public function enqueue_assets() {
		if ( ! SHC4WC_Plugin::is_connected() ) {
			return;
		}

		wp_enqueue_script(
			'shc4wc-sureforms-payment',
			SHC4WC_PLUGIN_URL . 'assets/js/sureforms-payment.js',
			array( 'jquery' ),
			SHC4WC_VERSION,
			true
		);

		wp_localize_script(
			'shc4wc-sureforms-payment',
			'shc4wcSureForms',
			array(
				'method' => self::METHOD,
				'i18n'   => array(
					'label' => __( 'You will complete payment on Square\'s secure checkout page.', 'payments-connect-square' ),
				),
			)
		);
	}

	/**
	 * @return void
	 */
	public function maybe_render_success_notice() {
		if ( empty( $_GET['shc4wc_sureforms_paid'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			return;
		}

		SHC4WC_Hosted_Checkout_Flow::enqueue_success_styles();
		SHC4WC_Hosted_Checkout_Flow::render_success_notice(
			esc_html__( 'Thank you — your Square payment was received and your form was submitted.', 'payments-connect-square' )
		);
	}

	/**
	 * @param array $form_data Form data.
	 * @return array|null
	 */
	private static function find_payment_field( $form_data ) {
		foreach ( $form_data as $field_name => $field_value ) {
			if ( false === strpos( (string) $field_name, 'srfm-payment-' ) ) {
				continue;
			}
			$decoded = is_string( $field_value ) ? json_decode( $field_value, true ) : $field_value;
			if ( ! is_array( $decoded ) ) {
				continue;
			}
			return array(
				'key'   => (string) $field_name,
				'value' => $decoded,
			);
		}
		return null;
	}

	/**
	 * @param array $payment_value Payment JSON.
	 * @param array $form_data     Form data.
	 * @return float
	 */
	private static function resolve_amount( $payment_value, $form_data ) {
		if ( ! empty( $payment_value['amount'] ) ) {
			$raw = $payment_value['amount'];
			if ( is_numeric( $raw ) ) {
				return (float) $raw / ( ! empty( $payment_value['zeroDecimal'] ) ? 1 : 100 );
			}
		}

		unset( $form_data );
		return 0;
	}

	/**
	 * @param array $form_data Form data.
	 * @return array
	 */
	private static function extract_buyer( $form_data ) {
		$customer = array(
			'email'       => '',
			'given_name'  => '',
			'family_name' => '',
			'phone'       => '',
			'wp_user_id'  => get_current_user_id(),
		);

		foreach ( (array) $form_data as $key => $value ) {
			if ( ! is_scalar( $value ) ) {
				continue;
			}
			$key   = (string) $key;
			$value = (string) $value;
			if ( false !== strpos( $key, 'email' ) && is_email( $value ) ) {
				$customer['email'] = sanitize_email( $value );
			}
		}

		return $customer;
	}

	/**
	 * @return string
	 */
	private static function resolve_return_url() {
		$referer = wp_get_referer();
		return $referer ? $referer : home_url( '/' );
	}
}
