<?php
/**
 * Editor Blocks.
 *
 * @author    Wpayme <hi@wpayme.com>
 * @copyright 2024-2025 Wpayme
 * @license   GPL-3.0-or-later
 * @package   Wpayme\WordPress\Pay
 */

namespace Wpayme\WordPress\Pay\Forms;

use Wpayme\WordPress\Number\Number;
use Wpayme\WordPress\Number\Parser as NumberParser;
use Wpayme\WordPress\Money\Money;
use Wpayme\WordPress\Pay\Forms\FormsSource;
use Wpayme\WordPress\Pay\Payments\Payment;
use Wpayme\WordPress\Pay\Plugin;
use WP_Error;
use WP_Query;
use WP_REST_Request;
use WP_REST_Response;

/**
 * Blocks
 *
 * @author  Reüel van der Steege
 * @since   2.5.0
 * @version 2.1.7
 */
class BlocksModule {
	/**
	 * Forms integration.
	 *
	 * @var Integration
	 */
	private $integration;

	/**
	 * Constructs and initializes a blocks module.
	 *
	 * @param Integration $integration Reference to the forms integration.
	 */
	public function __construct( Integration $integration ) {
		$this->integration = $integration;
		add_action( 'init', [ $this, 'register_block_types' ] );
		add_action( 'init', [ $this, 'register_scripts' ] );
	}

	/**
	 * Setup.
	 *
	 * @return void
	 */
	public function setup() {
		global $wp_version;

		// Initialize.
		add_action( 'init', [ $this, 'register_scripts' ] );
		add_action( 'init', [ $this, 'register_block_types' ] );

		add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_styles' ] );

		// Source text and description.
		add_filter( 'wpayme_payment_source_url_' . FormsSource::BLOCK_PAYMENT_FORM, [ $this, 'source_url' ], 10, 2 );
		add_filter( 'wpayme_payment_source_text_' . FormsSource::BLOCK_PAYMENT_FORM, [ $this, 'source_text' ], 10, 2 );
		add_filter( 'wpayme_payment_source_description_' . FormsSource::BLOCK_PAYMENT_FORM, [ $this, 'source_description' ], 10, 2 );
	}

	/**
	 * Register scripts.
	 *
	 * @return void
	 */
	public function register_scripts() {
		// Register editor script.
		$min = SCRIPT_DEBUG ? '' : '.min';

		wp_register_script(
			'wpayme-payment-form-editor',
			plugins_url( '/blocks-jsx/payment-form/index.js', dirname( __FILE__ ) ),
			[ 
				'wp-blocks', 
				'wp-components', 
				'wp-block-editor', 
				'wp-element',
				'wp-i18n'
			],
			wpayme_pay_plugin()->get_version(),
			false
		);

		// Get available forms
		$forms = [];
		$query = new WP_Query([
			'post_type' => 'wpayme_pay_form',
			'posts_per_page' => -1,
			'orderby' => 'title',
			'order' => 'ASC'
		]);

		if ($query->have_posts()) {
			while ($query->have_posts()) {
				$query->the_post();
				$forms[] = [
					'label' => get_the_title(),
					'value' => (string)get_the_ID()
				];
			}
		}
		wp_reset_postdata();

		// Add a default "Select a form" option
		array_unshift($forms, [
			'label' => __('Select a form', 'wpayme'),
			'value' => ''
		]);

		// Localize script.
		wp_localize_script(
			'wpayme-payment-form-editor',
			'wpayme_payment_form',
			[
				'title'              => _x( 'WPayme - Payment Form', 'Block', 'wpayme' ),
				'label_add_form'     => __( 'Add form', 'wpayme' ),
				'label_amount'       => __( 'Amount', 'wpayme' ),
				'label_select_form'  => __( 'Select Form', 'wpayme' ),
				'forms'              => $forms
			]
		);
	}

	/**
	 * Register block types.
	 *
	 * @return void
	 */
	public function register_block_types() {
		// error_log('Registering WPayme Payment Form Block');
		register_block_type(
			'wpayme-pay/payment-form',
			[
				'title'           => __( 'WPayme - Payment Form', 'wpayme' ),
				'icon'            => 'welcome-widgets-menus',
				'category'        => 'widgets',
				'render_callback' => [ $this, 'render_payment_form_block' ],
				'editor_script'   => 'wpayme-payment-form-editor',
				'editor_style'    => 'wpayme-pay-forms',
				'style'           => 'wpayme-pay-forms',
				'attributes'      => [
					'amount' => [
						'type'    => 'string',
						'default' => '0',
					],
					'formId' => [
						'type'    => 'string',
						'default' => '',
					],
				]
			]
		);
		// error_log('WPayme Payment Form Block Registered');
	}

	/**
	 * Enqueue styles.
	 *
	 * @return void
	 */
	public function enqueue_styles() {
		wp_enqueue_style(
			'wpayme-pay-forms',
			plugins_url( '/assets/css/forms.css', __DIR__ ),
			[],
			wpayme_pay_plugin()->get_version()
		);

		// Add error message styles
		wp_add_inline_style('wpayme-pay-forms', '
			.wpayme-error {
				padding: 15px;
				margin: 10px 0;
				background-color: #f8d7da;
				border: 1px solid #f5c6cb;
				border-radius: 4px;
				color: #721c24;
			}
		');
	}

	/**
	 * Render payment form block.
	 *
	 * @param array $attributes Attributes.
	 * @param string $content Block content.
	 *
	 * @return string
	 */
	public function render_payment_form_block( $attributes, $content = '' ) {
		// If we're in the editor, return the content as is
		if (is_admin()) {
			return $content;
		}

		try {
			// Amount.
			$amounts = [];

			if ( ! empty( $attributes['amount'] ) ) {
				try {
					$amounts[] = Number::from_mixed( $attributes['amount'] );
				} catch ( \Exception $e ) {
					try {
						$parser = new NumberParser();
						$amounts[] = $parser->parse( $attributes['amount'] );
					} catch ( \Exception $e ) {
						$amounts = [];
					}
				}
			}

			// If form ID is provided, get form settings
			if (empty($attributes['formId'])) {
				return sprintf(
					'<div class="wpayme-error">%s</div>',
					esc_html__('Please select a payment form.', 'wpayme')
				);
			}

			$form_id = intval($attributes['formId']);
			
			// Check if form exists
			$form = get_post($form_id);
			if (!$form || $form->post_type !== 'wpayme_pay_form') {
				return sprintf(
					'<div class="wpayme-error">%s</div>',
					esc_html__('Selected form not found.', 'wpayme')
				);
			}

			// Form settings.
			$args = [
				'amounts'   => $amounts,
				'html_id'   => sprintf( 'wpayme-pay-payment-form-%s', $form_id ),
				'source'    => FormsSource::BLOCK_PAYMENT_FORM,
				'source_id' => $form_id,
				'form_id'   => $form_id,
				'post_id'   => get_the_ID(),
			];

			// Get form settings from post meta
			$form_settings = get_post_meta($form_id, 'wpayme_pay_form_settings', true);
			if ($form_settings) {
				$args = array_merge($args, $form_settings);
			}

			// Check valid gateway.
			$config_id = get_option( 'wpayme_pay_config_id' );
			$gateway = Plugin::get_gateway( $config_id );

			if ( null === $gateway ) {
				return sprintf(
					'<div class="wpayme-error">%s</div>',
					esc_html__('No payment gateway found. Please configure your payment settings.', 'wpayme')
				);
			}

			$this->enqueue_styles();

			// Debug information
			/*
			if (defined('WP_DEBUG') && WP_DEBUG) {
				error_log('WPayme Form Args: ' . print_r($args, true));
			}
			*/

			// Return form output.
			$output = $this->integration->get_form_output( $args );
			
			if (empty($output)) {
				// Debug information
				/*
				if (defined('WP_DEBUG') && WP_DEBUG) {
					error_log('WPayme Form Output Empty');
					error_log('Form ID: ' . $form_id);
					error_log('Form Settings: ' . print_r($form_settings, true));
				}
				*/
				return sprintf(
					'<div class="wpayme-error">%s</div>',
					esc_html__('Unable to render payment form. Please check your form settings.', 'wpayme')
				);
			}

			return $output;

		} catch (\Exception $e) {
			// Debug information
			/*
			if (defined('WP_DEBUG') && WP_DEBUG) {
				error_log('WPayme Form Error: ' . $e->getMessage());
			}
			*/
			return sprintf(
				'<div class="wpayme-error">%s</div>',
				esc_html__('An error occurred while rendering the payment form.', 'wpayme')
			);
		}
	}

	/**
	 * Source text filter.
	 *
	 * @param string  $text    The source text to filter.
	 * @param Payment $payment The payment for the specified source text.
	 *
	 * @return string
	 */
	public function source_text( $text, Payment $payment ) {
		$text = __( 'Payment Form Block', 'wpayme' );

		if ( empty( $payment->source_id ) ) {
			return $text;
		}

		$link = get_edit_post_link( intval( $payment->source_id ) );

		if ( null === $link ) {
			return $text;
		}

		$text .= '<br />';

		$text .= sprintf(
			'<a href="%s">%s</a>',
			esc_url( $link ),
			esc_html( strval( $payment->source_id ) )
		);

		return $text;
	}

	/**
	 * Source description filter.
	 *
	 * @param string  $text    The source text to filter.
	 * @param Payment $payment The payment for the specified source text.
	 *
	 * @return string
	 */
	public function source_description( $text, Payment $payment ) {
		$text = __( 'Payment Form Block', 'wpayme' ) . '<br />';

		return $text;
	}

	/**
	 * Source URL.
	 *
	 * @param string  $url     Source URL.
	 * @param Payment $payment Payment.
	 *
	 * @return string
	 */
	public function source_url( $url, Payment $payment ) {
		if ( empty( $payment->source_id ) ) {
			return $url;
		}

		$link = get_edit_post_link( intval( $payment->source_id ) );

		if ( null === $link ) {
			return $url;
		}

		return $link;
	}
}
