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

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

class SHC4WC_MetForm {

	/** @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_action( 'mf_form_settings_tab_content', array( $this, 'render_form_settings' ), 20 );
		add_action( 'metform_before_store_form_data', array( $this, 'maybe_start_payment' ), 1, 4 );
		add_action( 'wp_enqueue_scripts', array( $this, 'maybe_enqueue_success_styles' ), 20 );
	}

	/**
	 * @return void
	 */
	public function render_form_settings() {
		if ( ! SHC4WC_Plugin::is_connected() ) {
			return;
		}
		?>
		<div class="mf-input-group mf-box-style">
			<label class="attr-input-label">
				<input type="checkbox" value="1" name="mf_shc4wc_square" class="mf-admin-control-input">
				<span><?php esc_html_e( 'Payments Square Connect (Hosted Checkout):', 'payments-connect-square' ); ?></span>
			</label>
			<span class="mf-input-help">
				<?php esc_html_e( 'Redirect buyers to Square Hosted Checkout after submit. Requires a payment amount field in the form.', 'payments-connect-square' ); ?>
			</span>
		</div>
		<div class="mf-input-group">
			<label class="attr-input-label" for="mf_shc4wc_amount_field">
				<?php esc_html_e( 'Square amount field name', 'payments-connect-square' ); ?>
			</label>
			<input type="text" name="mf_shc4wc_amount_field" id="mf_shc4wc_amount_field" class="attr-form-control" placeholder="<?php esc_attr_e( 'e.g. mf-number', 'payments-connect-square' ); ?>">
			<span class="mf-input-help"><?php esc_html_e( 'MetForm input name that contains the payment amount (number field).', 'payments-connect-square' ); ?></span>
		</div>
		<?php
	}

	/**
	 * @param int   $form_id       Form id.
	 * @param array $form_data     Submitted data.
	 * @param array $form_settings Form settings.
	 * @param array $attributes    Extra attributes.
	 * @return void
	 */
	public function maybe_start_payment( $form_id, $form_data, $form_settings, $attributes ) {
		unset( $attributes );
		if ( empty( $form_settings['mf_shc4wc_square'] ) ) {
			return;
		}
		if ( ! empty( $form_data['mf_payment_completed'] ) && '1' === (string) $form_data['mf_payment_completed'] ) {
			return;
		}

		$amount = self::resolve_amount( $form_data, $form_settings );
		if ( $amount <= 0 ) {
			wp_send_json(
				array(
					'status' => 0,
					'error'  => array( esc_html__( 'Enter a valid payment amount.', 'payments-connect-square' ) ),
				)
			);
		}

		$title = ! empty( $form_settings['form_title'] ) ? (string) $form_settings['form_title'] : sprintf( __( 'MetForm %d', 'payments-connect-square' ), (int) $form_id );

		$started = SHC4WC_Hosted_Checkout_Flow::start_one_time_payment(
			array(
				'type'        => 'metform',
				'amount'      => $amount,
				'currency'    => ! empty( $form_settings['mf_payment_currency'] ) ? (string) $form_settings['mf_payment_currency'] : SHC4WC_Hosted_Checkout_Flow::default_currency(),
				'description' => sprintf( __( 'MetForm: %s', 'payments-connect-square' ), $title ),
				'line_name'   => $title,
				'customer'    => self::extract_buyer( $form_data ),
				'payload'     => array(
					'form_id'     => (int) $form_id,
					'form_data'   => $form_data,
					'settings'    => $form_settings,
					'return_url'  => self::resolve_return_url( $form_settings ),
				),
			)
		);

		if ( is_wp_error( $started ) ) {
			wp_send_json(
				array(
					'status' => 0,
					'error'  => array( $started->get_error_message() ),
				)
			);
		}

		wp_send_json(
			array(
				'status' => 1,
				'data'   => array(
					'redirect_to' => $started['redirect'],
					'message'     => esc_html__( 'Redirecting to Square…', 'payments-connect-square' ),
				),
			)
		);
	}

	/**
	 * @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( 'metform', $ref, $key );
		if ( ! is_array( $stored ) ) {
			wp_safe_redirect( home_url( '/' ) );
			exit;
		}

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

		if ( $form_id > 0 && class_exists( '\MetForm\Core\Entries\Action' ) ) {
			$form_data['mf_payment_completed'] = '1';
			$file_data = array();
			$page_id   = url_to_postid( wp_get_referer() ? wp_get_referer() : home_url( '/' ) );
			\MetForm\Core\Entries\Action::instance()->submit( $form_id, $form_data, $file_data, $page_id );
		}

		$url = ! empty( $stored['return_url'] ) ? (string) $stored['return_url'] : self::resolve_return_url( $settings );
		$url = SHC4WC_Hosted_Checkout_Flow::add_paid_query_arg( $url, 'shc4wc_metform_paid' );
		wp_safe_redirect( $url );
		exit;
	}

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

	/**
	 * @param array $form_data     Submitted data.
	 * @param array $form_settings Form settings.
	 * @return float
	 */
	private static function resolve_amount( $form_data, $form_settings ) {
		$field = ! empty( $form_settings['mf_shc4wc_amount_field'] ) ? (string) $form_settings['mf_shc4wc_amount_field'] : '';
		if ( '' !== $field && isset( $form_data[ $field ] ) ) {
			return (float) $form_data[ $field ];
		}

		foreach ( (array) $form_data as $key => $value ) {
			if ( is_numeric( $value ) && ( false !== stripos( (string) $key, 'amount' ) || false !== stripos( (string) $key, 'price' ) || false !== stripos( (string) $key, 'number' ) ) ) {
				return (float) $value;
			}
		}

		return 0;
	}

	/**
	 * @param array $form_settings Form settings.
	 * @return string
	 */
	private static function resolve_return_url( $form_settings ) {
		if ( ! empty( $form_settings['redirect_to'] ) ) {
			return (string) $form_settings['redirect_to'];
		}
		$referer = wp_get_referer();
		return $referer ? $referer : home_url( '/' );
	}

	/**
	 * @param array $form_data Submitted 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 ) {
			$key = (string) $key;
			if ( ! is_scalar( $value ) ) {
				continue;
			}
			$value = (string) $value;
			if ( '' === $customer['email'] && ( false !== stripos( $key, 'email' ) ) ) {
				$customer['email'] = sanitize_email( $value );
			}
			if ( '' === $customer['phone'] && false !== stripos( $key, 'phone' ) ) {
				$customer['phone'] = sanitize_text_field( $value );
			}
			if ( '' === $customer['given_name'] && false !== stripos( $key, 'first' ) ) {
				$customer['given_name'] = sanitize_text_field( $value );
			}
			if ( '' === $customer['family_name'] && false !== stripos( $key, 'last' ) ) {
				$customer['family_name'] = sanitize_text_field( $value );
			}
		}

		return $customer;
	}
}
