<?php
namespace KnitPayUPI\Gateways\UpiQR\PhonePe;

use KnitPayUPI\Gateways\UpiQR\KnitPayUPIGateway;
use Pronamic\WordPress\Pay\Payments\Payment;
use Pronamic\WordPress\Pay\Payments\PaymentStatus;
use Exception;
use KnitPay\Gateways\PaymentMethods;
use Pronamic\WordPress\Pay\Core\PaymentMethod;

/**
 * Title: PhonePe Business Gateway
 * Copyright: 2020-2026 Knit Pay
 *
 * @author Knit Pay
 * @version 1.2.0.0
 * @since 1.2.0.0
 */
class Gateway extends KnitPayUPIGateway {
	private $api;

	/**
	 * Constructs and initializes an UPI QR gateway
	 *
	 * @param Config $config
	 *            Config.
	 */
	public function __construct( Config $config ) {     
		parent::__construct( $config );

		$this->add_support( 'bulk_payment_status_request' );

		$this->api = new API( $config );

		$this->merchant_verified = true; // TODO: Implement merchant verification logic
	}

	/**
	 * Start.
	 *
	 * @see KnitPayUPIGateway::start()
	 *
	 * @param Payment $payment
	 *            Payment.
	 */
	public function start( Payment $payment ) {
		parent::start( $payment );
		$transaction_id = preg_replace( '/[^a-zA-Z0-9\s]/', '', $payment->get_transaction_id() );
		$payment->set_transaction_id( $transaction_id );

		// Check connection.
		$this->refresh_token();

		$result = $this->get_gateway_data(
			$payment,
			[
				'phonepe_type'     => 'transactions_list',
				'current_user_mid' => $this->config->group_value,
				'timestamp'        => $payment->get_date()->getTimestamp(),
			]
		);

		$payment->set_meta( 'phonepe_status_cs', $result->data->phonepe_data );
		$payment->set_meta( 'kpp_charge_id', $result->id );
	}

	protected function register_payment_methods() {
		parent::register_payment_methods();

		$this->register_payment_method( new PaymentMethod( PaymentMethods::UPI_INTENT_PHONEPE ) );
	}

	public function get_output_fields( Payment $payment ) {
		$data = parent::get_output_fields( $payment );

		$data['tn'] = $data['tr'];

		return $data;
	}

	protected function get_bulk_transaction_data( Payment $payment ) {
		if ( '' === $this->config->refresh_token ) {
			throw new Exception( 'PhonePe for Business is not connected' );
		}

		if ( time() > $this->config->expires_at ) {
			$this->refresh_token();
		}

		$transaction_list = $this->api->get_transaction_list( $payment, $payment->get_meta( 'phonepe_status_cs' ) );

		$transactions = [];
		foreach ( $transaction_list->results as $transaction ) {
			if ( ! property_exists( $transaction, 'paymentState' ) ) {
				continue;
			}

			$transactions[] = [
				'kp_transaction_id' => $transaction->transactionNote,
				'utr'               => $transaction->utr,
				'amount'            => $transaction->amount / 100,
				'status'            => Statuses::transform( $transaction->paymentState ),
				'provider_response' => $transaction,
			];
		}

		return $transactions;
	}

	private function refresh_token() {
		if ( '' === $this->config->refresh_token ) {
			throw new Exception( 'PhonePe for Business is not connected' );
		}

		try {
			$token_data = $this->api->refresh_token();
		} catch ( Exception $e ) {
			if ( str_contains( $e->getMessage(), 'Please login' ) || str_contains( $e->getMessage(), 'Authorization failed' ) ) {
				delete_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_phonepe_device_fingerprint' );
				delete_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_phonepe_fingerprint' );
				delete_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_phonepe_refresh_token' );
				delete_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_phonepe_token' );
				delete_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_phonepe_expires_at' );
				delete_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_phonepe_user_group_id' );
				delete_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_phonepe_group_value' );
			}

			// TODO send warning email to WordPress Admin.

			throw $e;
		}

		if ( $this->config->refresh_token !== $token_data->refreshToken ) {
			update_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_phonepe_refresh_token', $token_data->refreshToken );
			update_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_phonepe_token', $token_data->token );
			update_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_phonepe_expires_at', $token_data->expiresAt - 900 );
		}
	}
}
