<?php
/**
 * Shared Square refund helpers for WPForms and Fluent Forms.
 *
 * @package SHC4WC
 */

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

class SHC4WC_Refunds {
	/**
	 * Issue a refund through the Square Payments API.
	 *
	 * @param string $payment_id       Square Payment id.
	 * @param float  $amount_major     Amount in major currency units.
	 * @param string $currency         ISO currency code.
	 * @param string $idempotency_seed Unique seed for idempotency key.
	 * @return array{refund_id:string,status:string}|WP_Error
	 */
	public static function process_refund( $payment_id, $amount_major, $currency, $idempotency_seed ) {
		$payment_id = sanitize_text_field( (string) $payment_id );
		if ( '' === $payment_id ) {
			return new WP_Error(
				'shc4wc_refund_no_payment',
				__( 'Square payment ID was not found. Wait for the customer to return from Square, then try again.', 'payments-connect-square' )
			);
		}

		$amount_major = (float) $amount_major;
		if ( $amount_major <= 0 ) {
			return new WP_Error( 'shc4wc_refund_invalid_amount', __( 'Refund amount must be greater than zero.', 'payments-connect-square' ) );
		}

		$settings = SHC4WC_Plugin::get_settings();
		$api      = new SHC4WC_API( $settings );
		$response = $api->create_refund(
			$payment_id,
			$amount_major,
			$currency,
			sanitize_key( (string) $idempotency_seed ) . '_' . wp_generate_password( 12, false, false )
		);

		if ( is_wp_error( $response ) ) {
			$api->log( 'Square refund failed', array( 'payment_id' => $payment_id, 'error' => $response->get_error_data() ), 'error' );
			return new WP_Error( 'shc4wc_refund_failed', self::format_square_refund_error( $response ) );
		}

		$refund    = isset( $response['refund'] ) && is_array( $response['refund'] ) ? $response['refund'] : array();
		$status    = isset( $refund['status'] ) ? strtoupper( (string) $refund['status'] ) : '';
		$refund_id = isset( $refund['id'] ) ? sanitize_text_field( (string) $refund['id'] ) : '';

		if ( in_array( $status, array( 'FAILED', 'REJECTED' ), true ) ) {
			return new WP_Error(
				'shc4wc_refund_rejected',
				sprintf(
					/* translators: %s: Square refund status. */
					__( 'Square rejected the refund (status: %s).', 'payments-connect-square' ),
					$status
				)
			);
		}

		return array(
			'refund_id' => $refund_id,
			'status'    => $status,
		);
	}

	/**
	 * @param WP_Error $error Square API error.
	 * @return string
	 */
	public static function format_square_refund_error( WP_Error $error ) {
		$data = $error->get_error_data();
		if ( is_array( $data ) && ! empty( $data['data']['errors'] ) && is_array( $data['data']['errors'] ) ) {
			$first = $data['data']['errors'][0];
			if ( ! empty( $first['detail'] ) ) {
				return sprintf(
					/* translators: %s: Square API error detail. */
					__( 'Square refund failed: %s', 'payments-connect-square' ),
					sanitize_text_field( (string) $first['detail'] )
				);
			}
			if ( ! empty( $first['code'] ) ) {
				return sprintf(
					/* translators: %s: Square API error code. */
					__( 'Square refund failed (code: %s).', 'payments-connect-square' ),
					sanitize_text_field( (string) $first['code'] )
				);
			}
		}

		$message = $error->get_error_message();
		if ( is_string( $message ) && '' !== $message ) {
			return $message;
		}

		return __( 'Square refund failed. Please try again.', 'payments-connect-square' );
	}

	/**
	 * Square Dashboard transaction URL for a payment id.
	 *
	 * @param string $transaction_id Square Payment id.
	 * @param bool   $test_mode      Sandbox vs live.
	 * @return string
	 */
	public static function square_dashboard_transaction_url( $transaction_id, $test_mode = false ) {
		$transaction_id = sanitize_text_field( (string) $transaction_id );
		if ( '' === $transaction_id ) {
			return '';
		}

		$base = $test_mode
			? 'https://squareupsandbox.com/dashboard/'
			: 'https://squareup.com/t/cmtp_performance/pr_developers/d_partnerships/p_0010L00001tJz7nQAC/?route=dashboard/';

		return $base . 'sales/transactions/' . rawurlencode( $transaction_id );
	}

	/**
	 * Whether an id is an internal hosted-checkout reference (not a Square Payment id).
	 *
	 * @param string $id Stored transaction / charge id.
	 * @return bool
	 */
	public static function is_internal_checkout_reference( $id ) {
		$id = (string) $id;
		if ( '' === $id ) {
			return true;
		}

		return (bool) preg_match( '/^(wpforms_|fluentform_)/', $id );
	}

	/**
	 * Parse Square order id from a Fluent Forms payment note.
	 *
	 * @param string $note Payment note text.
	 * @return string
	 */
	public static function parse_square_order_id_from_note( $note ) {
		$note = (string) $note;
		if ( preg_match( '/order:([A-Za-z0-9_-]+)/', $note, $matches ) ) {
			return sanitize_text_field( $matches[1] );
		}
		if ( preg_match( '/—\s*([A-Za-z0-9_-]+)\s*$/u', $note, $matches ) ) {
			return sanitize_text_field( $matches[1] );
		}
		return '';
	}

	/**
	 * Parse Square payment link id from a Fluent Forms payment note.
	 *
	 * @param string $note Payment note text.
	 * @return string
	 */
	public static function parse_payment_link_id_from_note( $note ) {
		$note = (string) $note;
		if ( preg_match( '/link:([A-Za-z0-9_-]+)/', $note, $matches ) ) {
			return sanitize_text_field( $matches[1] );
		}
		return '';
	}
}
