<?php
/**
 * Meta Box Gateway Settings
 *
 * @author Wpayme <hi@wpayme.com>
 * @copyright 2024-2025 Wpayme
 * @license GPL-3.0-or-later
 * @package Wpayme\WordPress\Pay
 * @var \Wpayme\WordPress\Pay\Plugin       $plugin     Plugin.
 * @var string                               $gateway_id Gateway ID.
 * @var int                                  $config_id  Configuration ID.
 * @var \Wpayme\WordPress\Pay\Core\Gateway $gateway    Gateway.
 */

use Wpayme\WordPress\Html\Element;
use Wpayme\WordPress\Pay\Admin\AdminGatewayPostType;
use Wpayme\WordPress\Pay\Util;
use Wpayme\WordPress\Pay\Webhooks\WebhookRequestInfo;

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

$wpayme_integration = $plugin->gateway_integrations->get_integration( $gateway_id );

if ( null === $wpayme_integration ) {
	return;
}

$wpayme_fields = $wpayme_integration->get_settings_fields();

$wpayme_sections = [
	'general'         => (object) [
		'title'  => __( 'General', 'wpayme' ),
		'fields' => [],
	],
	'advanced'        => (object) [
		'title'  => __( 'Advanced', 'wpayme' ),
		'fields' => [],
	],
	'feedback'        => (object) [
		'title'  => __( 'Feedback', 'wpayme' ),
		'fields' => [],
	],
	'payment_methods' => (object) [
		'title'  => __( 'Payment Methods', 'wpayme' ),
		'fields' => [
			[
				'section'  => 'payment_methods',
				'title'    => __( 'Supported Payment Methods', 'wpayme' ),
				'type'     => 'custom',
				'callback' => function () use ( $gateway, $gateway_id ) {
					AdminGatewayPostType::settings_payment_methods( $gateway, $gateway_id );
				},
			],
		],
	],
];

// Feedback.
if ( $wpayme_integration->supports( 'webhook' ) ) {
	$wpayme_fields[] = [
		'section'  => 'feedback',
		'title'    => __( 'Webhook Status', 'wpayme' ),
		'type'     => 'custom',
		'callback' => function () use ( $gateway, $gateway_id, $config_id ) {
			AdminGatewayPostType::settings_webhook_log( $gateway, $gateway_id, $config_id );
		},
	];
}

// Check if webhook configuration is needed.
if ( $wpayme_integration->supports( 'webhook' ) && ! $wpayme_integration->supports( 'webhook_no_config' ) ) {
	$wpayme_webhook_config_needed = true;

	$wpayme_log = get_post_meta( $config_id, '_wpayme_gateway_webhook_log', true );

	if ( ! empty( $wpayme_log ) ) {
		$wpayme_log = json_decode( $wpayme_log );

		$wpayme_request_info = WebhookRequestInfo::from_json( $wpayme_log );

		// Validate log request URL against current home URL.
		if ( str_starts_with( $wpayme_request_info->get_request_url(), home_url( '/' ) ) ) {
			$wpayme_webhook_config_needed = false;
		}
	}

	if ( $wpayme_webhook_config_needed ) {
		$wpayme_sections['feedback']->title = sprintf(
			'⚠️ %s',
			$wpayme_sections['feedback']->title
		);

		$wpayme_fields[] = [
			'section'  => 'general',
			'title'    => __( 'Transaction feedback', 'wpayme' ),
			'type'     => 'custom',
			'callback' => function () {
				printf(
					'⚠️ %s',
					esc_html__(
						'Processing gateway transaction feedback in the background requires additional configuration.',
						'wpayme'
					)
				);
			},
		];
	}
}

// Sections.
foreach ( $wpayme_fields as $wpayme_field_id => $wpayme_field ) {
	$wpayme_section = 'general';

	if ( array_key_exists( 'section', $wpayme_field ) ) {
		$wpayme_section = $wpayme_field['section'];
	}

	if ( ! array_key_exists( $wpayme_section, $wpayme_sections ) ) {
		$wpayme_section = 'general';
	}

	$wpayme_sections[ $wpayme_section ]->fields[] = $wpayme_field;
}

$wpayme_sections = array_filter(
	$wpayme_sections,
	function ( $wpayme_section ) {
		return ! empty( $wpayme_section->fields );
	}
);

?>
<div class="wpayme-pay-tabs">
	<ul class="wpayme-pay-tabs-items">

		<?php foreach ( $wpayme_sections as $wpayme_section ) : ?>

			<li>
				<?php echo esc_html( $wpayme_section->title ); ?>
			</li>

		<?php endforeach; ?>

	</ul>

	<?php foreach ( $wpayme_sections as $wpayme_section ) : ?>

		<div class="wpayme-pay-tab">
			<div class="wpayme-pay-tab-block gateway-config-section-header">
				<h4 class="wpayme-pay-cloak"><?php echo esc_html( $wpayme_section->title ); ?></h4>
			</div>

			<table class="form-table">

				<?php

				foreach ( $wpayme_section->fields as $wpayme_field ) :

					$wpayme_classes = [];

					if ( isset( $wpayme_field['methods'] ) ) {
						foreach ( $wpayme_field['methods'] as $wpayme_method ) {
							$wpayme_classes[] = 'setting-' . $wpayme_method;
						}
					}

					if ( isset( $wpayme_field['group'] ) ) {
						$wpayme_classes[] = $wpayme_field['group'];
					}

					if ( isset( $wpayme_field['id'] ) ) {
						$wpayme_field_id = $wpayme_field['id'];
					} elseif ( isset( $wpayme_field['meta_key'] ) ) {
						$wpayme_field_id = $wpayme_field['meta_key'];
					} else {
						$wpayme_field_id = uniqid();
					}

					?>
					<tr class="<?php echo esc_attr( implode( ' ', $wpayme_classes ) ); ?>">
						<th scope="row">
							<?php

							if ( array_key_exists( 'title', $wpayme_field ) ) {
								printf(
									'<label for="%s">%s</label>',
									esc_attr( $wpayme_field_id ),
									esc_html( $wpayme_field['title'] )
								);
							}

							if ( isset( $wpayme_field['tooltip'] ) && ! empty( $wpayme_field['tooltip'] ) ) {
								printf(
									'<span class="dashicons dashicons-editor-help wpayme-pay-tip" title="%s"></span>',
									esc_attr( $wpayme_field['tooltip'] )
								);
							}

							?>
						</th>
						<td>
							<?php

							$wpayme_field = (array) $wpayme_field;

							$wpayme_attributes         = [];
							$wpayme_attributes['id']   = $wpayme_field_id;
							$wpayme_attributes['name'] = $wpayme_field_id;

							$wpayme_classes = [];
							if ( isset( $wpayme_field['classes'] ) ) {
								$wpayme_classes = $wpayme_field['classes'];
							}

							if ( isset( $wpayme_field['readonly'] ) && $wpayme_field['readonly'] ) {
								$wpayme_attributes['readonly'] = 'readonly';

								$wpayme_classes[] = 'readonly';
							}

							if ( isset( $wpayme_field['required'] ) && $wpayme_field['required'] ) {
								$wpayme_attributes['required'] = 'required';
							}

							if ( isset( $wpayme_field['size'] ) ) {
								$wpayme_attributes['size'] = $wpayme_field['size'];
							}

							if ( in_array( $wpayme_field['type'], [ 'text', 'password', 'textarea', 'select' ], true ) ) {
								$wpayme_classes[] = 'wpayme-pay-form-control';
							}

							if ( in_array( $wpayme_field['type'], [ 'textarea' ], true ) ) {
								$wpayme_classes[] = 'wpayme-pay-form-control-lg';
							}

							if ( ! empty( $wpayme_classes ) ) {
								$wpayme_attributes['class'] = implode( ' ', $wpayme_classes );
							}

							$wpayme_value = '';
							if ( isset( $wpayme_field['meta_key'] ) ) {
								$wpayme_attributes['name'] = $wpayme_field['meta_key'];

								$wpayme_value = get_post_meta( $config_id, $wpayme_field['meta_key'], true );
							} elseif ( isset( $wpayme_field['value'] ) ) {
								$wpayme_value = $wpayme_field['value'];
							}

							// Set default.
							if ( empty( $wpayme_value ) && isset( $wpayme_field['default'] ) ) {
								$wpayme_default = $wpayme_field['default'];

								/**
								 * An empty value can also be an empty string, this
								 * should not always be overwritten with the default
								 * value. Therefore we check if there is any kind of
								 * meta.
								 *
								 * @link https://developer.wordpress.org/reference/functions/get_post_meta/
								 */
								$wpayme_meta = get_post_meta( $config_id, $wpayme_field['meta_key'], false );

								if ( empty( $wpayme_meta ) ) {
									$wpayme_value = \is_callable( $wpayme_default ) ? call_user_func( $wpayme_default, $config_id ) : $wpayme_default;
								}
							}

							switch ( $wpayme_field['type'] ) {
								case 'text':
								case 'password':
									$wpayme_attributes['type']  = $wpayme_field['type'];
									$wpayme_attributes['value'] = $wpayme_value;

									$wpayme_element = new Element( 'input', $wpayme_attributes );

									$wpayme_element->output();

									break;
								case 'number':
									$wpayme_attributes['type']  = $wpayme_field['type'];
									$wpayme_attributes['value'] = $wpayme_value;

									if ( isset( $wpayme_field['min'] ) ) {
										$wpayme_attributes['min'] = $wpayme_field['min'];
									}

									if ( isset( $wpayme_field['max'] ) ) {
										$wpayme_attributes['max'] = $wpayme_field['max'];
									}

									$wpayme_element = new Element( 'input', $wpayme_attributes );

									$wpayme_element->output();

									break;
								case 'checkbox':
									$wpayme_attributes['type']  = $wpayme_field['type'];
									$wpayme_attributes['value'] = '1';

									/**
									 * Unchecked HTML checkboxes are not part of an HTML form POST request.
									 * Should the settings API delete settings that are not posted, or should
									 * it set the value to false? We simplify this by adding an hidden HTML
									 * input with `0` value. If the checkbox is checked it will post two
									 * values under the same name. PHP will work with the last occurrence.
									 *
									 * @link https://stackoverflow.com/questions/1746507/authoritative-position-of-duplicate-http-get-query-keys#8971514
									 */
									printf(
										'<input type="hidden" name="%s" value="0" />',
										\esc_attr( $wpayme_field_id )
									);

									if ( true === (bool) $wpayme_value ) {
										$wpayme_attributes['checked'] = 'checked';
									}

									$wpayme_element = new Element( 'input', $wpayme_attributes );

									$wpayme_element->output();

									printf( ' ' );

									printf(
										'<label for="%s">%s</label>',
										esc_attr( $wpayme_attributes['id'] ),
										esc_html( $wpayme_field['label'] )
									);

									break;
								case 'textarea':
									$wpayme_attributes['rows'] = 4;
									$wpayme_attributes['cols'] = 65;

									$wpayme_element = new Element( 'textarea', $wpayme_attributes );

									$wpayme_element->children[] = $wpayme_value;

									$wpayme_element->output();

									break;
								case 'file':
									$wpayme_attributes['type'] = 'file';

									$wpayme_element = new Element( 'input', $wpayme_attributes );

									$wpayme_element->output();

									break;
								case 'select':
									$wpayme_element = new Element( 'select', $wpayme_attributes );

									foreach ( $wpayme_field['options'] as $wpayme_key => $wpayme_label ) {
										$wpayme_option = new Element( 'option', [ 'value' => $wpayme_key ] );

										$wpayme_option->children[] = $wpayme_label;

										if ( $wpayme_value === (string) $wpayme_key ) {
											$wpayme_option->attributes['selected'] = 'selected';
										}

										$wpayme_element->children[] = $wpayme_option;
									}

									$wpayme_element->output();

									break;
								case 'optgroup':
									printf( '<fieldset>' );
									printf( '<legend class="screen-reader-text">%s</legend>', esc_html( $wpayme_field['title'] ) );

									foreach ( $wpayme_field['options'] as $wpayme_key => $wpayme_label ) {
										printf(
											'<label>%s %s</label><br />',
											sprintf(
												'<input type="radio" value="%s" name="%s" %s />',
												esc_attr( $wpayme_key ),
												esc_attr( $wpayme_attributes['name'] ),
												checked( $wpayme_value, $wpayme_key, false )
											),
											esc_html( $wpayme_label )
										);
									}

									break;
							}

							if ( isset( $wpayme_field['description'] ) ) {
								printf(
									'<p class="wpayme-pay-description description">%s</p>',
									\wp_kses(
										$wpayme_field['description'],
										[
											'a'    => [
												'href'   => true,
												'target' => true,
											],
											'br'   => [],
											'code' => [],
										]
									)
								);
							}

							if ( isset( $wpayme_field['callback'] ) ) {
								$wpayme_callback = $wpayme_field['callback'];

								call_user_func( $wpayme_callback, $wpayme_field );
							}

							?>
						</td>
					</tr>

				<?php endforeach; ?>

			</table>
		</div>

	<?php endforeach; ?>

</div>
