<?php

namespace KnitPay\Extensions\KnitPayPaymentButton;

use Pronamic\WordPress\Money\Currency;
use Pronamic\WordPress\Money\Money;
use Pronamic\WordPress\Pay\Plugin;
use Pronamic\WordPress\Pay\Payments\Payment;
use Pronamic\WordPress\Pay\Payments\PaymentStatus as Core_Statuses;

/**
 * Title: Knit Pay - Payment Button Gateway
 * Description:
 * Copyright: 2020-2026 Knit Pay
 * Company: Knit Pay
 *
 * @author  knitpay
 * @since   8.75.0.0
 */

/**
 * Prevent loading this file directly
 */
defined( 'ABSPATH' ) || exit();

class Gateway {

	/**
	 * Bootstrap
	 */
	public function __construct() {
		// Initiate Gutenberg Payment Button Block.
		global $wp_version;
		if ( function_exists( 'register_block_type' ) && version_compare( $wp_version, '6.1', '>=' ) ) {
			$blocks_module = new PaymentButtonBlock();
			$blocks_module->setup();
		}

		// Initialize Elementor Payment Button Widget.
		add_action( 'elementor/widgets/register', [ $this, 'register_payment_button_widget' ] );

		// Add Javascript Dependencies.
		add_action( 'wp_enqueue_scripts', [ $this, 'knit_pay_payment_button_dependencies' ] );

		// Add Ajax listener.
		add_action( 'wp_ajax_nopriv_knit_pay_payment_button_submit', [ $this, 'ajax_payment_button_submit' ] );
		add_action( 'wp_ajax_knit_pay_payment_button_submit', [ $this, 'ajax_payment_button_submit' ] );
	}

	/**
	 * Register scripts.
	 */
	function knit_pay_payment_button_dependencies() {
		/* Scripts */
		wp_register_script( 'knit-pay-payment-button-frontend', plugins_url( 'build/view.js', __FILE__ ), [ 'jquery' ], KNITPAY_VERSION, true );

		wp_localize_script(
			'jquery',
			'knit_pay_payment_button_ajax_object',
			[
				'ajaxurl'      => admin_url( 'admin-ajax.php' ),
				'loading_icon' => \esc_url( admin_url( 'images/loading.gif' ) ),
			]
		);
	}

	function register_payment_button_widget( $widgets_manager ) {
		if ( trait_exists( 'Elementor\Includes\Widgets\Traits\Button_Trait' ) ) {
			$widgets_manager->register( new ElementorPaymentButtonWidget() );
		}
	}

	public function ajax_payment_button_submit() {
		$amount              = Helper::get_post_variable( 'amount' );
		$currency            = Helper::get_post_variable( 'currency' );
		$payment_description = Helper::get_post_variable( 'payment_description' );
		$config_id           = Helper::get_post_variable( 'config_id' );
		$honeypot_field      = Helper::get_post_variable( 'knit_pay_honeypot_field' );
		$knit_pay_nonce      = Helper::get_post_variable( 'knit_pay_nonce' );
		$old_payment         = get_pronamic_payment_by_meta( 'knit_pay_nonce', $knit_pay_nonce );
		$nonce_action        = "knit_pay_payment_button|{$amount}|{$currency}|{$payment_description}|{$config_id}|{$honeypot_field}";

		if ( ! wp_verify_nonce( $knit_pay_nonce, $nonce_action ) ) {
			echo wp_json_encode(
				[
					'status'    => 'error',
					'error_msg' => __( 'Nonce Missmatch!', 'knit-pay-lang' ),
				]
			);
			exit;
		} elseif ( null !== $old_payment && Core_Statuses::FAILURE !== $old_payment->get_status() ) {
			// Execute a redirect.
			echo wp_json_encode(
				[
					'status'       => 'success',
					'redirect_url' => $old_payment->get_pay_redirect_url(),
				]
			);
			exit;
		}

		// SPAM PROTECTION: Honeypot field check
		if ( ! empty( $honeypot_field ) ) {
			$honeypot_value = Helper::get_post_variable( $honeypot_field );
			if ( ! empty( $honeypot_value ) ) {
				// Bot detected - honeypot field was filled
				echo wp_json_encode(
					[
						'status'    => 'error',
						'error_msg' => __( 'Invalid submission detected.', 'knit-pay-lang' ),
					]
				);
				exit;
			}
		}

		if ( empty( $amount ) ) {
			$amount = 0;
		}

		$payment_method = 'knit_pay';
		$current_user   = wp_get_current_user();

		// Use default gateway if no configuration has been set.
		if ( empty( $config_id ) ) {
			$config_id = get_option( 'pronamic_pay_config_id' );
		}

		$gateway = Plugin::get_gateway( $config_id );

		if ( ! $gateway ) {
			echo wp_json_encode(
				[
					'status'    => 'error',
					'error_msg' => __( 'Gateway configuration was not found. If you are an admin, kindly create a payment gateway configuration.', 'knit-pay-lang' ),
				]
			);
			exit;
		}

		/**
		 * Build payment.
		 */
		$payment = new Payment();

		$payment->source   = 'knit-pay-payment-button';
		$payment->order_id = uniqid();
		$payment->source   = uniqid();

		$payment->set_description( Helper::get_description( $payment, $payment_description ) );

		$payment->title = Helper::get_title( $payment );

		// Customer.
		$payment->set_customer( Helper::get_customer( $current_user ) );

		// Address.
		$payment->set_billing_address( Helper::get_address( $current_user ) );

		// Currency.
		$currency = Currency::get_instance( $currency );

		// Amount.
		$payment->set_total_amount( new Money( $amount, $currency ) );

		// Method.
		$payment->set_payment_method( $payment_method );

		// Configuration.
		$payment->config_id = $config_id;

		try {
			$payment = Plugin::start_payment( $payment );

			update_post_meta( $payment->get_id(), 'knit_pay_nonce', $knit_pay_nonce );

			// Execute a redirect.
			echo wp_json_encode(
				[
					'status'       => 'success',
					'redirect_url' => $payment->get_pay_redirect_url(),
				]
			);
			exit;
		} catch ( \Exception $e ) {
			echo wp_json_encode(
				[
					'status'    => 'error',
					'error_msg' => $e->getMessage(),
				]
			);
			exit;
		}
	}

	public static function instance() {
		return new self();
	}
}
