<?php

namespace Simplyin\Simplyin_W_Plugin\Payments\Gateway\Model;

use Exception;
use Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Api\PaymentsApi;
use Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Configuration;
use Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPayRequest;
use Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPayRequestCustomerPaymentData;
use Simplyin\Simplyin_W_Plugin\Lib\Remote\SimplyInApi\Model\PaymentsPayRequestPaymentMethodData;
use Simplyin\Simplyin_W_Plugin\Lib\Session\Simplyin_Session;
use Simplyin\Simplyin_W_Plugin\Payments\Gateway\Gateway_Helper;

class Payment_Type_Add_Card extends Abstract_Card_Payment implements Payment_Type_Interface {

	private string $ott = '';
	public string $last_digits = '';
	public string $organization = '';
	public string $card_name;
	public string $card_save_checkbox = '';


	public function process_payment( Order_Data $order_data ) {
		global $simplyin_config;
		$simplyin_api_url = $simplyin_config['backendSimplyIn'];

		try {
			$order = $order_data->get_order();

			$simplyin_auth_token = ( new Simplyin_Session() )->get( 'simplyin_auth_token' );
			$registration_token = $order->get_meta( '_simplyin_registration_auth_token' );

			$is_new_user = ! $this->is_simplyin_user_logged();
			if ( $is_new_user && ! empty( $registration_token ) ) {
				$simplyin_auth_token = $registration_token;
			}

			$config = new Configuration();
			if ( ! empty( $simplyin_auth_token ) ) {
				$config->setApiKey( 'api_token', $simplyin_auth_token );
			}

			$config->setApiKey( 'X-Auth-Merchant-Api-Key',
				get_option( 'simplyin_api_key' ) );
			$config->setHost( $simplyin_api_url );

		$api                = new PaymentsApi( null, $config );
		$this->payment_uuid = $this->generate_random_uuid();

		// Set logo for UI display.
		$this->logo_url = $this->get_card_provider_logo( $this->organization );

		$payment_method_data = new PaymentsPayRequestPaymentMethodData();
		$payment_method_data->setOtt( $this->ott );
		$payment_method_data->setCardName( $this->card_name !== '' ? $this->card_name : 'Card 1' );
		$payment_method_data->setLastDigitsOfCardNumber( $this->last_digits );
		$payment_method_data->setCardProvider( $this->organization );

		$should_save_card = 'true' === $this->card_save_checkbox;
		if ( ! $should_save_card && 'false' === $this->card_save_checkbox ) {
			$has_registration_token = ! empty( $registration_token );

			simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
				sprintf( "[Payment_Type_Add_Card] [process_payment] [saveCard check] checkbox='%s', is_new_user=%s, has_registration_token=%s",
					$this->card_save_checkbox,
					$is_new_user ? 'yes' : 'no',
					$has_registration_token ? 'yes' : 'no'
				),
				'payments'
			);

			if ( $is_new_user && $has_registration_token ) {
				$should_save_card = true;
				simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
					sprintf( "[Payment_Type_Add_Card] [process_payment] [Auto-enabling saveCard for new user registration]"),
					'payments'
				);
			}
		}

		$payment_method_data->setSaveCard( $should_save_card );

		// Log payment method data being sent to API.
		simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
			sprintf( "[Payment_Type_Add_Card] [process_payment] Payment method data: card_provider='%s', last_digits='%s', card_name='%s', checkbox='%s', saveCard=%s",
				esc_html( $this->organization ),
				esc_html( $this->last_digits ),
				esc_html( $this->card_name ),
				esc_html( $this->card_save_checkbox ),
				$should_save_card ? 'true' : 'false'
			),
			'payments'
		);

			$request = new PaymentsPayRequest();
			$request->setPaymentMethodId( $this->get_id() );
			$request->setPaymentId( $this->payment_uuid );
			$request->setTitle( 'Order #' . $order->get_id() );
			$request->setAmount( Gateway_Helper::normalize_price( $order->get_total() ) );
			$request->setCurrency( get_woocommerce_currency() );
			$request->setReturnUrl( $order->get_checkout_order_received_url() );
			$request->setWebhookUrl( Gateway_Helper::get_webhook_url( $order ) );

			$request->setPaymentMethodData( $payment_method_data );


			// Build debug snapshot as associative array to avoid stdClass access issues
			$debug = json_decode( wp_json_encode( $request->jsonSerialize() ), true );

			if ( false === $this->is_simplyin_user_logged() ) {
				$customerPaymentData = new PaymentsPayRequestCustomerPaymentData();
				$customerPaymentData->setEmail( $order->get_billing_email() );
				$customerPaymentData->setId( '' );
				$customerPaymentData->setFirstName( $order->get_billing_first_name() );
				$customerPaymentData->setLastName( $order->get_billing_last_name() );
				$customerPaymentData->setPhone( $order->get_billing_phone() );
				$request->setCustomerPaymentData( $customerPaymentData );
				$debugCustomerPaymentData     = [
					'email'     => $customerPaymentData->getEmail(),
					'FirstName' => $customerPaymentData->getFirstName(),
					'LastName'  => $customerPaymentData->getLastName(),
					'Phone'     => $customerPaymentData->getPhone(),
				];
				$debug['CustomerPaymentData'] = $debugCustomerPaymentData;
			}

			// Log request snapshot for diagnostics (without sensitive data).
			simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
				sprintf( "[Payment_Type_Add_Card] [paymentsPay request] %s",
					wp_json_encode( $debug )
				),
				'payments' );

		// Log API call attempt.
		simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
			sprintf( "[Payment_Type_Add_Card] [process_payment] Calling Simply.IN API paymentsPay with card_provider='%s'",
				esc_html( $this->organization )
			),
			'payments'
		);

			$raw = $api->paymentsPay( $request );

			// Log successful API response.
			simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
				sprintf("[Payment_Type_Add_Card] [process_payment] Simply.IN API SUCCESS. Status: '%s', ProviderPaymentId: '%s'",
					esc_html($raw->getStatus() ?? 'unknown'),
					esc_html($raw->getProviderPaymentId() ?? 'unknown')
				),
				'payments'
			);

			// Clean up registration token after successful payment processing
			// Token is no longer needed and should be removed for security
			if ( ! empty( $registration_token ) ) {
				$order->delete_meta_data( '_simplyin_registration_auth_token' );
				$order->save_meta_data();
				simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
					sprintf( "[Payment_Type_Add_Card] [process_payment] [Registration token cleaned up] [order_id: %s]",
						$order->get_id()
					),
					'payments'
				);
			}

		} catch ( Exception $e ) {

		// Log API error details.
		simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
			sprintf( "[Payment_Type_Add_Card] [process_payment] Simply.IN API ERROR. Card provider: '%s', Error: '%s'",
				esc_html( $this->organization ?? 'unknown' ),
				esc_html( $e->getMessage() )
			),
			'payments'
		);

			$this->handle_error_customer_message( $e );
			$order_data->update_selected_payment_method( $this );

			simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
				sprintf( "[Payment_Type_Add_Card] [process_payment] %s",
					wp_json_encode( [
						'error'   => $e->getMessage(),
						'request' => $debug,
					] ),
				),
				'payments' );

			throw new Exception( esc_html( $e->getMessage() ) );
		} catch ( \Throwable $e ) {

			// Capture any non-Exception throwables as failure visible on thank-you page
			$this->customer_error_message = $e->getMessage();
			$order_data->update_selected_payment_method( $this );

			simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
				sprintf( "[Payment_Type_Add_Card] [process_payment throwable] %s",
					wp_json_encode( [
						'error'   => $e->getMessage(),
						'request' => $debug ?? [],
					] )
				),
				'payments' );

			throw new Exception( esc_html( $e->getMessage() ) );
		} finally {
			$this->ott = '***';
		}

		$this->payment_status      = $raw->getStatus();
		$this->provider_payment_id = $raw->getProviderPaymentId();
		$this->registered_at       = $raw->getRegisteredAt();
		// If provider requires 3DS, redirectUrl may be present – store it so thankyou page can redirect.
		if ( method_exists( $raw, 'getRedirectUrl' ) ) {
			$this->redirect_url = $raw->getRedirectUrl();
		}

		$order_data->update_selected_payment_method( $this );

		simplyin()->get_simplyin_logger()->log_if_wpdebug_on(
			sprintf( "[Payment_Type_Add_Card] [process_payment] %s",
				wp_json_encode( [
					'request'      => $debug,
					'raw response' => $raw,
				] ),
			),
			'payments' );


	}

	private function get_card_provider_logo( string $provider ): string {
		switch ( $provider ) {
			case 'visa':
				return simplyin()->get_plugin_url() . 'public/img/visa.svg';
			case 'mastercard':
				return simplyin()->get_plugin_url() . 'public/img/mastercard.svg';
			case 'maestro':
				return simplyin()->get_plugin_url() . 'public/img/maestro.svg';
			default:
				// Fallback to mastercard for unknown brands.
				return simplyin()->get_plugin_url() . 'public/img/mastercard.svg';
		}
	}

	public function configure_on_checkout() {

		if ( isset( $_POST['simplyin_checkout_token'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['simplyin_checkout_token'] ) ),
				'simplyin_checkout_nonce' ) ) {

			throw new Exception( 'wp_verify_nonce classic checkout failed' );

		} elseif ( isset( $_POST['simplyin_blocks_token'] ) && ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['simplyin_blocks_token'] ) ),
				'simplyin_blocks_nonce' ) ) {
			throw new Exception( 'wp_verify_nonce block checkout failed' );

		} elseif ( ! isset( $_POST['simplyin_checkout_token'] ) && ! isset( $_POST['simplyin_blocks_token'] ) ) {
			throw new Exception( 'Nonce not found' );
		}


		if ( isset( $_POST['simplyin_card_name'] ) ) {
			$this->card_name = sanitize_text_field( wp_unslash( $_POST['simplyin_card_name'] ) );
		} else {
			$this->card_name = 'Card 1';
		}

		if ( isset( $_POST['simplyin_card_save_checkbox'] ) ) {
			$this->card_save_checkbox = sanitize_text_field( wp_unslash( $_POST['simplyin_card_save_checkbox'] ) );
		} else {
			throw new Exception( 'simplyin_card_save_checkbox field not found' );
		}

		if ( isset( $_POST['simplyin_organization'] ) ) {
			$this->organization = sanitize_text_field( wp_unslash( $_POST['simplyin_organization'] ) );
		} else {
			throw new Exception( 'simplyin_organization field not found' );
		}

		if ( isset( $_POST['simplyin_last_digits'] ) ) {
			$this->last_digits = sanitize_text_field( wp_unslash( $_POST['simplyin_last_digits'] ) );
		} else {
			throw new Exception( 'simplyin_last_digits field not found' );
		}

		if ( isset( $_POST['simplyin_ott'] ) ) {
			$this->ott = sanitize_text_field( wp_unslash( $_POST['simplyin_ott'] ) );
		} else {
			throw new Exception( 'simplyin_ott field not found' );
		}


	}

	public function set_payment_status( string $payment_status ) {
		$this->payment_status = $payment_status;
	}
}
