<?php

namespace KnitPayUPI\Gateways\UpiQR;

use KnitPay\Gateways\Integration as KnitPayGatewayIntegration;
use Pronamic\WordPress\Pay\Payments\Payment;
use Pronamic\WordPress\Pay\Payments\PaymentStatus;
use WP_Query;
use Pronamic\WordPress\Pay\Core\Util as Core_Util;
use Pronamic\WordPress\Pay\Plugin;
use Exception;
use KnitPay\Gateways\UpiQR\Integration as UPI_Integration;

/**
 * Title: UPI QR Integration
 * Copyright: 2020-2026 Knit Pay
 *
 * @author  Knit Pay
 * @version 1.0.0
 * @since   4.1.0
 */
class KnitPayUPIIntegration extends UPI_Integration {
	private $gateway_name;
	private $terms_url;
	private $refresh_connection;
	private $short_id;

	/**
	 * Construct UPI QR integration.
	 *
	 * @param array $args Arguments.
	 */
	public function __construct( $args = [] ) {
		parent::__construct( $args );

		$this->gateway_name       = isset( $args['gateway_name'] ) ? $args['gateway_name'] : $this->get_name();
		$this->terms_url          = isset( $args['terms_url'] ) ? $args['terms_url'] : '';
		$this->short_id           = isset( $args['short_id'] ) ? $args['short_id'] : $this->get_id(); // Used for Refresh connection scheduler.
		$this->refresh_connection = isset( $args['refresh_connection'] ) ? $args['refresh_connection'] : false;

		// Add Ajax listener.
		add_action( 'wp_ajax_nopriv_knit_pay_upi_qr_payment_status_check', [ $this, 'ajax_payment_status_check' ] );
		add_action( 'wp_ajax_knit_pay_upi_qr_payment_status_check', [ $this, 'ajax_payment_status_check' ] );

		// Payment status check events are scheduled after payment is expired. We want to check status once more.
		add_action( 'knit_pay_upi_payment_status_check', [ $this, 'check_status' ], 10, 2 );
	}

	/**
	 * Setup gateway integration.
	 *
	 * @return void
	 */
	public function setup() {
		parent::setup();

		// Refresh connection to keep session active.
		if ( $this->refresh_connection ) {
			add_action( 'knit_pay_upi_' . $this->short_id . '_refresh_connection', [ $this, 'refresh_connection' ], 10, 1 );
		}
	}

	/**
	 * Get settings fields.
	 *
	 * @return array
	 */
	protected function get_pro_about_settings_fields( $fields ) {
		// Prerequisite.
		$fields[] = [
			'section'  => 'general',
			'type'     => 'custom',
			'title'    => 'Prerequisite',
			'callback' => function () {
				$knit_pay_pro_setup_url = admin_url( 'admin.php?page=knit_pay_pro_setup_page' );
				$link                   = '<a target="_blank" href="' . $knit_pay_pro_setup_url . '">' . __( 'Knit Pay >> Knit Pay UPI Setup', 'knit-pay-lang' ) . '</a>';
				$message                = sprintf( __( 'Please visit the %s page to configure "Knit Pay - UPI".', 'knit-pay-lang' ), $link );

				echo '<ol><li>We rely on the third-party service provider RapidAPI for the setup of Knit Pay UPI. RapidAPI will charge you based on your monthly usage.</li>
                    	<li>Choose a plan that suits your usage. Each plan includes a certain
                    		number of free transactions. If you exceed the transaction quota,
                    		additional charges will apply for receiving extra transactions. <br> <a
                    		target="_blank"
                    		href="https://rapidapi.com/knitpay/api/knit-pay-upi/pricing">https://rapidapi.com/knitpay/api/knit-pay-upi/pricing</a></li>
                        <li>' . $message . '</li>
                    </ol>';
			},
		];

		// Terms and Conditions.
		$fields[] = [
			'section'  => 'general',
			'type'     => 'custom',
			'title'    => 'Terms and Conditions',
			'callback' => function () {
				echo '<ol>
                    <li>We generate QR codes on your behalf using your UPI/VPA ID so that you can accept payments with ease.</li>
                    <li>Knit Pay UPI is not a payment gateway service, and we are not involved in the payment process in any way. Your Merchant Account will be used for collecting payments.</li>
                    <li>We do not collect any of your payments in our account. The payment made by the user through the QR code will be received in your merchant account.</li>
                    <li>We are not liable for any fraudulent activity that takes place with your merchant account.</li>
                    <li>We might also suspend your RapidAPI subscription if any fraudulent activity gets detected.</li>
                    <li>We are not responsible for the suspension of your merchant account due to any reason.</li>
					<li>Use of plugins/codes like these might not be allowed as per the terms of the UPI Service provider. Use this plugin at your own risk.</li>
                    <li>Use this plugin at your own risk, we are not liable for any of your losses.</li>
                 </ol>';
			},
		];

		return $fields;
	}

	public function get_about_settings_fields( $fields ) {
		$fields = $this->get_pro_about_settings_fields( $fields );

		// Gateway Terms and Conditions.
		$fields[] = [
			'section'  => 'general',
			'type'     => 'custom',
			'title'    => $this->gateway_name . ' Terms and Conditions',
			'callback' => function () {
				$terms_string = 'Terms and Conditions';
				if ( ! empty( $this->terms_url ) ) {
					$terms_string = '<a href="' . $this->terms_url . '" target="_blank">Terms and Conditions</a>';
				}

				echo "Use this integration only if you have read and agree with the {$terms_string} of " . $this->gateway_name . '.';
			},
		];


		return $fields;
	}

	public function get_setup_settings_fields( $fields ) {
		$fields = parent::get_setup_settings_fields( $fields );

		unset( $fields['payment_instruction'] );
		unset( $fields['mobile_payment_instruction'] );
		unset( $fields['payment_success_status'] );
		unset( $fields['hide_mobile_qr'] );
		unset( $fields['hide_pay_button'] );

		return $fields;
	}

	protected function get_connection_status_field( $fields ) {
		try {
			$this->is_connected();

			$fields[] = [
				'section'  => 'general',
				'type'     => 'custom',
				'title'    => 'Connected',
				'callback' => function () {
					echo '<span class="dashicons dashicons-yes"></span>';
				},
			];
		} catch ( Exception $e ) {
			$fields[] = [
				'section'  => 'general',
				'type'     => 'custom',
				'title'    => 'Connected',
				'callback' => function () {
					echo '<span class="dashicons dashicons-no"></span>';
				},
			];

			$message = '<strong>Knit Pay</strong> - The connection to ' . $this->gateway_name . ' could not be established.';
			wp_admin_notice( $message, [ 'type' => 'error' ] );
		}

		return $fields;
	}

	protected function get_supported_template_list() {
		return [
			'0' => 'Default',
			'4' => '4',
			'5' => '5',
		];
	}

	protected function is_connected() {
		return true;
	}

	/**
	 * Check status of the specified payment.
	 *
	 * @param int         $payment_id The payment ID to check.
	 * @param string|null $gateway_id The gateway ID to check against.
	 * @return void
	 */
	public function check_status( $payment_id = null, $gateway_id = null ) {
		// Check only if this payment belongs to this gateway.
		if ( $gateway_id !== $this->get_id() ) {
			return;
		}

		$payment = get_pronamic_payment( $payment_id );

		// No payment found, unable to check status.
		if ( null === $payment ) {
			return;
		}

		// Add note.
		$note = sprintf(
			/* translators: %s: Knit Pay UPI */
			__( 'Payment status check at gateway by %s.', 'knit-pay-lang' ),
			__( 'Knit Pay UPI', 'knit-pay-lang' )
		);

		$payment->add_note( $note );

		// Update payment.
		Plugin::update_payment( $payment, false );
	}

	public function ajax_payment_status_check() {
		$payment_id     = isset( $_POST['knit_pay_payment_id'] ) ? sanitize_text_field( $_POST['knit_pay_payment_id'] ) : '';
		$transaction_id = isset( $_POST['knit_pay_transaction_id'] ) ? sanitize_text_field( $_POST['knit_pay_transaction_id'] ) : '';
		$knit_pay_nonce = isset( $_POST['knit_pay_nonce'] ) ? sanitize_text_field( $_POST['knit_pay_nonce'] ) : '';

		$nonce_action = "knit_pay_payment_status_check|{$payment_id}|{$transaction_id}";

		if ( ! wp_verify_nonce( $knit_pay_nonce, $nonce_action ) ) {
			wp_send_json_error( __( 'Nonce Missmatch!', 'knit-pay-lang' ) );
		}

		$payment = get_pronamic_payment( $payment_id );

		if ( null === $payment ) {
			exit;
		}

		$gateway = $payment->get_gateway();
		if ( ! $gateway->supports( 'payment_status_request' ) ) {
			wp_send_json_error( __( 'Gateway does not support automatic payment status check.', 'knit-pay-lang' ) );
		}

		// Update status.
		try {
			$gateway->update_status( $payment );

			// Save New Status.
			if ( PaymentStatus::OPEN !== $payment->get_status() ) {
				$payment->save();
			}

			wp_send_json_success( $payment->get_status() );
		} catch ( \Exception $error ) {
			$message = $error->getMessage();

			// Maybe include error code in message.
			$code = $error->getCode();

			if ( $code > 0 ) {
				$message = \sprintf( '%s: %s', $code, $message );
			}

			// Add note.
			$payment->add_note( $message );

			wp_send_json_error( $message );
		}
	}

	/**
	 * Get gateway.
	 *
	 * Dynamically instantiates the Gateway class from the child class namespace if it exists,
	 * otherwise falls back to the base Gateway class.
	 *
	 * @param int $config_id Config ID.
	 * @return Gateway|object Gateway instance from child namespace or base Gateway class.
	 */
	public function get_gateway( $config_id ) {
		// Get the current class's fully qualified name
		$integration_class = get_class( $this );

		// Get the namespace of the current class
		$namespace = substr( $integration_class, 0, strrpos( $integration_class, '\\' ) );

		// Build the Gateway class name in the same namespace
		$gateway_class = $namespace . '\\Gateway';

		// Check if the Gateway class exists in the child namespace, otherwise fallback to base Gateway
		if ( class_exists( $gateway_class ) ) {
			return new $gateway_class( $this->get_config( $config_id ) );
		}

		// Fallback to base Gateway class
		return new Gateway( $this->get_config( $config_id ) );
	}
}
