<?php

namespace KnitPayUPI\Gateways\UpiQR\BharatPe;

use Pronamic\WordPress\Http\Facades\Http;
use Exception;

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

/**
 * Title: BharatPe API Client
 * Copyright: 2020-2026 Knit Pay
 *
 * @author  Knit Pay
 * @version 1.6.1.0
 * @since   1.3.0.0
 */
class Client {
	const CONNECTION_TIMEOUT = 20;

	private $config;

	public function __construct( Config $config ) {
		$this->config = $config;
	}

	public function init_session() {
		$response = wp_remote_get(
			'https://enterprise.bharatpe.in/',
			[
				'timeout' => self::CONNECTION_TIMEOUT,
			]
		);
		$html     = wp_remote_retrieve_body( $response );

		if ( empty( $html ) ) {
			throw new Exception( 'Could not retrieve CSRF token.' );
		}

		// Use DOMDocument to parse HTML and get csrf-token
		$doc = new \DOMDocument();
		@$doc->loadHTML( $html ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
		$metas = $doc->getElementsByTagName( 'meta' );

		$csrf_token = '';
		foreach ( $metas as $meta ) {
			if ( $meta->getAttribute( 'name' ) === 'csrf-token' ) {
				$csrf_token = $meta->getAttribute( 'content' );
				break;
			}
		}

		if ( empty( $csrf_token ) ) {
			update_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_bharatpe_integration_mode', 'manual' );
			throw new Exception( 'Connection in automatic mode failed, switching to manual mode.' );
		}

		$bharatpe_session = wp_remote_retrieve_cookie( $response, 'bharatpe_session' );

		update_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_bharatpe_bharatpe_session', $bharatpe_session );
		update_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_bharatpe_csrf_token', $csrf_token );
	}

	public function request_otp() {
		$response = wp_remote_post(
			'https://enterprise.bharatpe.in/v1/api/user/requestotp',
			[
				'body'    => [
					'mobile' => $this->config->phone_number,
					'_token' => $this->config->csrf_token,
				],
				'cookies' => $this->get_cookies(),
				'timeout' => self::CONNECTION_TIMEOUT,
			]
		);
		$result   = wp_remote_retrieve_body( $response );

		$result = json_decode( $result );

		$bharatpe_session = wp_remote_retrieve_cookie( $response, 'bharatpe_session' );
		update_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_bharatpe_bharatpe_session', $bharatpe_session );

		if ( isset( $result->success ) && $result->success ) {
			return $result;
		} elseif ( isset( $result->message ) ) {
			throw new Exception( $result->message );
		}

		throw new Exception( 'Something went wrong. Please try again later.' );
	}

	public function verify_otp( $otp ) {
		$response = wp_remote_post(
			'https://enterprise.bharatpe.in/v1/api/user/verifyotp',
			[
				'body'    => [
					'mobile' => $this->config->phone_number,
					'uuid'   => $this->config->uuid,
					'otp'    => $otp,
					'_token' => $this->config->csrf_token,
				],
				'cookies' => $this->get_cookies(),
				'timeout' => self::CONNECTION_TIMEOUT,
			]
		);
		$result   = wp_remote_retrieve_body( $response );

		$result = json_decode( $result );

		$bharatpe_session = wp_remote_retrieve_cookie( $response, 'bharatpe_session' );
		update_post_meta( $this->config->config_id, '_pronamic_gateway_upi_qr_bharatpe_bharatpe_session', $bharatpe_session );

		if ( isset( $result->success ) && $result->success ) {
			return $result;
		} elseif ( isset( $result->message ) ) {
			throw new Exception( $result->message );
		}

		throw new Exception( 'Something went wrong. Please try again later.' );
	}

	public function get_user_info() {
		$response = wp_remote_get(
			'https://enterprise.bharatpe.in/v1/api/userInfo',
			[
				'cookies' => $this->get_cookies(),
				'timeout' => self::CONNECTION_TIMEOUT,
			]
		);
		$result   = wp_remote_retrieve_body( $response );

		$result = json_decode( $result );

		if ( ! isset( $result ) ) {
			throw new Exception( 'Something went wrong. Please try again later.' );
		} elseif ( isset( $result->success ) && $result->success ) {
			return $result;
		} elseif ( property_exists( $result, 'message' ) ) {
			throw new Exception( $result->message );
		}

		throw new Exception( 'Something went wrong. Please try again later.' );
	}

	public function get_qr_code( $bharatpe_data ) {
		if ( '' === $this->config->token ) {
			throw new Exception( 'BharatPe for Business is not connected.' );
		}

		$response = wp_remote_get(
			'https://payments-tesseract.bharatpe.in/api/merchant/v1/downloadQr',
			[
				'body'    => json_decode( $bharatpe_data, true ),
				'headers' => $this->get_headers(),
				'timeout' => self::CONNECTION_TIMEOUT,
			]
		);
		$result   = wp_remote_retrieve_body( $response );

		$result = json_decode( $result );

		if ( ! isset( $result ) ) {
			throw new Exception( 'Something went wrong. Please try again later.' );
		}

		if ( $result->status ) {
			return $result->data->url;
		} else {
			throw new Exception( $result->responseMessage, $result->responseCode );
		}
	}

	public function get_transaction_details( $bharatpe_data ) {
		if ( '' === $this->config->token ) {
			throw new Exception( 'BharatPe for Business is not connected.' );
		} elseif ( empty( $this->config->connection_data ) ) {
			Integration::clear_config( $this->config->config_id );
			throw new Exception( 'BharatPe for Business is not connected.' );
		}

		if ( get_transient( 'knit_pay_upi_checking_status_' . $this->config->config_id ) ) {
			return;
		}
		set_transient( 'knit_pay_upi_checking_status_' . $this->config->config_id, true, 6 );

		$response = wp_remote_get(
			'https://payments-tesseract.bharatpe.in/api/v1/merchant/transactions',
			[
				'body'    => json_decode( $bharatpe_data, true ),
				'headers' => $this->get_headers(),
				'timeout' => self::CONNECTION_TIMEOUT,
			]
		);
		$result   = wp_remote_retrieve_body( $response );

		$result = json_decode( $result );

		if ( ! isset( $result ) ) {
			throw new Exception( 'Something went wrong. Please try again later.' );
		}

		if ( true === $result->status ) {
			return $result->data->transactions;
		} elseif ( isset( $result->responseCode ) && isset( $result->responseMessage ) ) {
			if ( '401' === $result->responseCode ) {
				Integration::clear_config( $this->config->config_id );
			}
			throw new Exception( $result->responseMessage, $result->responseCode );
		}
	}

	public function get_bharatpe_connection_data() {
		$data = [
			'mode'                => 'live',
			'gateway'             => 'bharat-pe',
			'source'              => 'config',
			'amount'              => '0',
			'currency'            => 'INR',
			'knitpay_version'     => KNITPAY_VERSION,
			'knitpay_upi_version' => KNITPAY_UPI_VERSION,
			'php_version'         => PHP_VERSION,
			'website_url'         => home_url( '/' ),
			'data'                => [
				'mid'            => $this->config->merchant_id,
				'phone_number'   => $this->config->phone_number,
				'transaction_id' => '',
			],
		];

		\KnitPayPro::check_knit_pay_pro_setup();

		$response = Http::post(
			\KNIT_PAY_UPI_RAPIDAPI_BASE_URL . 'payments/upi/request',
			[
				'body'    => wp_json_encode( $data ),
				'headers' => [
					'X-RapidAPI-Host' => \KNIT_PAY_UPI_RAPIDAPI_HOST,
					'X-RapidAPI-Key'  => get_option( 'knit_pay_pro_setup_rapidapi_key' ),
				],
				'timeout' => self::CONNECTION_TIMEOUT,
			]
		);

		$result = $response->json();

		if ( '403' === (string) $response->status() ) {
			$api_link = ' https://rapidapi.com/knitpay/api/knit-pay-upi/pricing';
			throw new Exception( 'RapidAPI Error: ' . $result->message . $api_link );
		} elseif ( '200' !== (string) $response->status() ) {
			throw new Exception( 'RapidAPI Error: ' . $result->message );
		}

		return $result->data->bharat_pe_data;
	}

	private function get_headers() {
		return [
			'token' => $this->config->token,
		];
	}

	private function get_cookies() {
		return [ $this->config->bharatpe_session ];
	}
}
