<?php

// namespace Sofort\SofortLib;

if (!defined('ABSPATH')) exit;  // Exit if accessed directly


use PayPalCheckoutSdk\Orders\OrdersCreateRequest;

function wpgv__doajax_voucher_pdf_save_func()
{

	// Get the nonce from POST data
	$nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';

	// Check nonce
	if (empty($nonce) || !wp_verify_nonce($nonce, 'voucher_form_verify')) {
		wp_send_json_error(array('message' => 'Invalid nonce'));
		wp_die();
	}

	$wpgv_enable_recaptcha = get_option('wpgv_enable_recaptcha') ? sanitize_text_field(get_option('wpgv_enable_recaptcha')) : '';
	$recaptchaSecretKey  = get_option('wpgv_recaptcha_secret_key') ? sanitize_text_field(get_option('wpgv_recaptcha_secret_key')) : '';
	$recaptcha_response = isset($_POST['recaptcha_response']) ? sanitize_text_field($_POST['recaptcha_response']) : '';

	if ($recaptcha_response && $wpgv_enable_recaptcha == 1) {

		$verifyUrl = 'https://www.google.com/recaptcha/api/siteverify';
		$response = wp_remote_post($verifyUrl, array(
			'body' => array(
				'secret' => $recaptchaSecretKey,
				'response' => $recaptcha_response,
				'remoteip' => $_SERVER['REMOTE_ADDR']
			)
		));


		$responseBody = wp_remote_retrieve_body($response);
		$result = json_decode($responseBody);
		if (!$result->success) {
			wp_send_json_error(array('message' => 'reCAPTCHA verification failed.'));
			exit();
		}
	}

	$template = sanitize_text_field(base64_decode($_POST['template']));
	$wpgv_hide_title_voucher = get_option('wpgv_hide_title_voucher') ? get_option('wpgv_hide_title_voucher') : 0;
	if ($wpgv_hide_title_voucher == 1) {
		$template_voucher = __('Gift voucher', 'gift-voucher');
	} else {
		$template_voucher = get_the_title($template);
	}

	$buyingfor = sanitize_text_field(base64_decode($_POST['buying_for']));
	$for = isset($_POST['for']) ? sanitize_text_field(base64_decode($_POST['for'])) : '';
	$from = isset($_POST['from']) ? sanitize_text_field(base64_decode($_POST['from'])) : '';
	$value = sanitize_text_field(base64_decode($_POST['value']));
	$message = isset($_POST['message']) ? sanitize_text_field(base64_decode($_POST['message'])) : '';
	$expiry = base64_decode($_POST['expiry']);

	$wpgv_coupon_code_type = get_option('wpgv_coupon_code_type') ? get_option('wpgv_coupon_code_type') : '';
	$wpgv_starting_coupon_number = get_option('wpgv_starting_coupon_number') ? get_option('wpgv_starting_coupon_number') : '';
	$wpgv_current_coupon_number = get_option('wpgv_current_coupon_number') ? get_option('wpgv_current_coupon_number') : '';
	$coupon_code_length = get_option('wpgv_coupon_code_length') ? get_option('wpgv_coupon_code_length') : 12;
	$code = null;

	if ($wpgv_coupon_code_type === "random") {
		$code = sanitize_text_field(base64_decode($_POST['code']));
	} else if ($wpgv_coupon_code_type === "incremental") {
		if (!empty($wpgv_current_coupon_number)) {
			$code = intval($wpgv_current_coupon_number);
		} else {

			$code = intval($wpgv_starting_coupon_number);
		}
	}

	$code = str_pad($code, $coupon_code_length, '0', STR_PAD_LEFT);

	$shipping = sanitize_text_field(base64_decode($_POST['shipping']));
	$shipping_email = isset($_POST['shipping_email']) ? sanitize_email(base64_decode($_POST['shipping_email'])) : '';
	$firstname = isset($_POST['firstname']) ? sanitize_text_field(base64_decode($_POST['firstname'])) : '';
	$lastname = isset($_POST['lastname']) ? sanitize_text_field(base64_decode($_POST['lastname'])) : '';
	$email = isset($_POST['email']) ? sanitize_email(base64_decode($_POST['email'])) : '';
	$address = isset($_POST['address']) ? sanitize_text_field(base64_decode($_POST['address'])) : '';
	$pincode = isset($_POST['pincode']) ? sanitize_text_field(base64_decode($_POST['pincode'])) : '';
	$shipping_method = isset($_POST['shipping_method']) ? base64_decode($_POST['shipping_method']) : '';
	$paymentmethod = sanitize_text_field(base64_decode($_POST['paymentmethod']));
	$send_email_date_time = isset($_POST['send_email_date_time']) ? base64_decode($_POST['send_email_date_time']) : 'send_instantly';


	$paytext = '';
	if ($paymentmethod == 'Per Invoice') {
		$paytext = __('Per Invoice', 'gift-voucher');
	} else {
		$paytext = $paymentmethod;
	}
	$seller_company_name = isset($_POST['seller_company_name']) ? base64_decode($_POST['seller_company_name']) : '';
	$seller_addr_line1 = isset($_POST['seller_addr_line1']) ? base64_decode($_POST['seller_addr_line1']) : '';
	$seller_addr_line2 = isset($_POST['seller_addr_line2']) ? base64_decode($_POST['seller_addr_line2']) : '';
	$seller_addr_line3 = isset($_POST['seller_addr_line3']) ? base64_decode($_POST['seller_addr_line3']) : '';
	$seller_addr_line4 = isset($_POST['seller_addr_line4']) ? base64_decode($_POST['seller_addr_line4']) : '';

	global $wpdb;
	$voucher_table 	= $wpdb->prefix . 'giftvouchers_list';
	$setting_table 	= $wpdb->prefix . 'giftvouchers_setting';
	$template_table = $wpdb->prefix . 'giftvouchers_template';
	$invoice_setting_table = $wpdb->prefix . 'giftvouchers_invoice_settings';

	$setting_options = $wpdb->get_row("SELECT * FROM $setting_table WHERE id = 1");
	$template_options = $wpdb->get_row("SELECT * FROM $template_table WHERE id = $template");
	$invoice_options = $wpdb->get_row("SELECT * FROM $invoice_setting_table WHERE id = 1");

	$style1_image = get_post_meta($template, 'style1_image', true);
	$style2_image = get_post_meta($template, 'style2_image', true);
	$style3_image = get_post_meta($template, 'style3_image', true);

	$style_images_array = array(
		$style1_image,
		$style2_image,
		$style3_image,
	);

	$images = $style_images_array ? $style_images_array : ['', '', ''];

	// Safely read color options (fallback to defaults if DB row is missing)
	$voucher_bg_hex = (isset($setting_options->voucher_bgcolor) ? $setting_options->voucher_bgcolor : '#ffffff');
	$voucher_color_hex = (isset($setting_options->voucher_color) ? $setting_options->voucher_color : '#000000');
	$invoice_color_hex = (isset($invoice_options->invoice_color) ? $invoice_options->invoice_color : '#000000');

	$voucher_bgcolor = wpgv_hex2rgb($voucher_bg_hex);
	$voucher_color = wpgv_hex2rgb($voucher_color_hex);
	$invoice_color = wpgv_hex2rgb($invoice_color_hex);



	$wpgv_hide_expiry = get_option('wpgv_hide_expiry') ? get_option('wpgv_hide_expiry') : 'yes';
	$wpgv_customer_receipt = get_option('wpgv_customer_receipt') ? get_option('wpgv_customer_receipt') : 0;
	$wpgv_expiry_date_format = get_option('wpgv_expiry_date_format') ? get_option('wpgv_expiry_date_format') : 'd.m.Y';
	$wpgv_enable_pdf_saving = get_option('wpgv_enable_pdf_saving') ? get_option('wpgv_enable_pdf_saving') : 0;
	$wpgv_add_extra_charges = get_option('wpgv_add_extra_charges_voucher') ? get_option('wpgv_add_extra_charges_voucher') : 0;

	// Get currency code early for use in Klarna integration
	$currency_code = isset($setting_options->currency_code) ? $setting_options->currency_code : $setting_options->currency;

	if (get_locale() == "cs_CZ" || get_locale() == 'sk_SK') {
		$currency = wpgv_price_format_cs_CZ($value);
	} else {
		$currency = wpgv_price_format($value);
	}
	$expiry_data = "";
	if ($wpgv_hide_expiry == 'no') {
		$expiry = __('No Expiration', 'gift-voucher');
		$expiry_data = __('No Expiry', 'gift-voucher');
	} else {
		$expiry = ($setting_options->voucher_expiry_type == 'days') ? rtrim(date_i18n($wpgv_expiry_date_format, strtotime('+' . $setting_options->voucher_expiry . ' days', time()))) : $setting_options->voucher_expiry;
		$expiry_data = $expiry;
	}

	if ($value == 0) {
		echo '<div class="wpgvmodaloverlay"><div class="wpgvmodalcontent">' . __('Error Occurred - Please check the amount and try again.', 'gift-voucher') . '<br><a href="">' . __('Load Page Again', 'gift-voucher') . '</a></div></div>';
		wp_die();
	}

	$upload = wp_upload_dir();
	$upload_dir = $upload['basedir'];
	$curr_time = time();
	$upload_dir = $upload_dir . '/voucherpdfuploads/' . $curr_time . $_POST['code'] . '.pdf';
	$upload_url = $curr_time . $_POST['code'];

	$formtype = 'voucher';
	$preview = false;

	if ($setting_options->is_style_choose_enable) {
		$voucher_style = sanitize_text_field(base64_decode($_POST['style']));
		$image_attributes = get_attached_file($images[$voucher_style]);
		$image = ($image_attributes) ? $image_attributes : get_option('wpgv_demoimageurl_voucher');
		$stripeimage = (wp_get_attachment_image_src($images[$voucher_style])) ? wp_get_attachment_image_src($images[$voucher_style]) : get_option('wpgv_demoimageurl_voucher');
	} else {
		$voucher_style = 0;
		$image_attributes = get_attached_file($images[0]);
		$image = ($image_attributes) ? $image_attributes : get_option('wpgv_demoimageurl_voucher');
		$stripeimage = (wp_get_attachment_image_src($images[0])) ? wp_get_attachment_image_src($images[0]) : get_option('wpgv_demoimageurl_voucher');
	}

	switch ($voucher_style) {
		case 0:
			// Use isolated PDF generation with safe wrapper
			$pdf = wpgv_create_pdf_safe();
			if ($pdf) {
				require_once(WPGIFT__PLUGIN_DIR . '/templates/pdfstyles/style1.php');
			}
			break;
		case 1:
			// Use isolated PDF generation with safe wrapper
			$pdf = wpgv_create_pdf_safe();
			if ($pdf) {
				require_once(WPGIFT__PLUGIN_DIR . '/templates/pdfstyles/style2.php');
			}
			break;
		case 2:
			// Use isolated PDF generation with safe wrapper
			$pdf = wpgv_create_pdf_safe();
			if ($pdf) {
				require_once(WPGIFT__PLUGIN_DIR . '/templates/pdfstyles/style3.php');
			}
			break;
		default:
			// Use isolated PDF generation with safe wrapper
			$pdf = wpgv_create_pdf_safe();
			if ($pdf) {
				require_once(WPGIFT__PLUGIN_DIR . '/templates/pdfstyles/style1.php');
			}
			break;
	}

	if ($wpgv_enable_pdf_saving) {
		$pdf->Output($upload_dir, 'F');
	} else {
		$pdf->Output('F', $upload_dir);
	}

	$wpdb->insert(
		$voucher_table,
		array(
			'order_type'		=> 'vouchers',
			'template_id' 		=> $template,
			'buying_for'		=> $buyingfor,
			'from_name' 		=> $for,
			'to_name' 			=> $from,
			'amount'			=> $value,
			'message'			=> $message,
			'shipping_type'		=> $shipping,
			'shipping_email'	=> $shipping_email,
			'firstname'			=> $firstname,
			'lastname'			=> $lastname,
			'email'				=> $email,
			'address'			=> $address,
			'postcode'			=> $pincode,
			'shipping_method'	=> $shipping_method,
			'pay_method'		=> $paymentmethod,
			'expiry'			=> $expiry_data,
			'couponcode'		=> $code,
			'voucherpdf_link'	=> $upload_url,
			'status'			=> 'unused',
			'payment_status'	=> 'Not Paid',
			'voucheradd_time'	=> current_time('mysql'),
			'email_send_date_time' => $send_email_date_time,
			'check_send_mail' => 'unsent',
		)
	);

	$lastid = $wpdb->insert_id;
	// coupon incremental
	if ($lastid && $wpgv_coupon_code_type === "incremental") {
		$coupon_code_length = get_option('wpgv_coupon_code_length') ? get_option('wpgv_coupon_code_length') : 12;
		$next_number = intval($code) + 1;
		$next_number_formatted = str_pad($next_number, $coupon_code_length, '0', STR_PAD_LEFT);
		update_option('wpgv_current_coupon_number', $next_number_formatted);
	}
	$voucher_order_by = __("Voucher ordered by", "gift-voucher");
	$message_e = __("Message:", "gift-voucher");
	WPGV_Gift_Voucher_Activity::record($lastid, 'create', '', $voucher_order_by . " " . $for . ',' . $message_e . " " . $message);

	$shipping_charges = 0;

	if ($shipping != 'shipping_as_email') {
		$preshipping_methods = explode(',', $setting_options->shipping_method);
		foreach ($preshipping_methods as $method) {
			$preshipping_method = explode(':', $method);
			if (trim(stripslashes($preshipping_method[1])) == trim(stripslashes($shipping_method))) {
				$value += trim($preshipping_method[0]);
				$shipping_charges = trim($preshipping_method[0]);
				break;
			}
		}
	}

	if ($wpgv_add_extra_charges != 0) {
		$value += $wpgv_add_extra_charges; // Add the extra charges to value
	}

	if ($invoice_options->is_invoice_active == 1) {
		$upload_dir = $upload['basedir'];
		$invoiceupload_dir = $upload_dir . '/voucherpdfuploads/' . $curr_time . $_POST['code'] . '-invoice.pdf';
		// Use isolated PDF generation for invoice
		$invoice = wpgv_create_pdf_safe();
		if ($invoice) {
			require_once(WPGIFT__PLUGIN_DIR . '/templates/pdfstyles/invoice-1.php');
		}
		if ($wpgv_enable_pdf_saving) {
			$invoice->Output($invoiceupload_dir, 'F');
		} else {
			$invoice->Output('F', $invoiceupload_dir);
		}
	}

	//Customer Receipt
	if ($wpgv_customer_receipt) {
		$upload_dir = $upload['basedir'];
		$receiptupload_dir = $upload_dir . '/voucherpdfuploads/' . $curr_time . $_POST['code'] . '-receipt.pdf';
		// Use isolated PDF generation for receipt
		$receipt = wpgv_create_pdf_safe();
		if ($receipt) {
			require_once(WPGIFT__PLUGIN_DIR . '/templates/pdfstyles/receipt.php');
		}
		if ($wpgv_enable_pdf_saving) {
			$receipt->Output($receiptupload_dir, 'F');
		} else {
			$receipt->Output('F', $receiptupload_dir);
		}
	}
	update_post_meta($lastid, 'wpgv_extra_charges', $wpgv_add_extra_charges);
	update_post_meta($lastid, 'wpgv_total_payable_amount', $value);

	$success_url = get_home_url() . '/voucher-payment-successful/?voucheritem=' . $lastid;
	$cancel_url = get_home_url() . '/voucher-payment-cancel/?voucheritem=' . $lastid;
	$notify_url = get_home_url() . '/voucher-payment-successful/?voucheritem=' . $lastid;

	$wpgv_paypal_client_id = get_option('wpgv_paypal_client_id') ? get_option('wpgv_paypal_client_id') : '';
	$wpgv_paypal_secret_key = get_option('wpgv_paypal_secret_key') ? get_option('wpgv_paypal_secret_key') : '';

	if ($paymentmethod == 'Paypal') {
		if (empty($wpgv_paypal_client_id) || empty($wpgv_paypal_secret_key)) {
			$error_message = "PayPal Client ID or Secret Key are both empty.";
			wp_send_json_error(array('message' => $error_message));
		} else {
			require_once(WPGIFT__PLUGIN_DIR . '/vendor/autoload.php');
			require_once(WPGIFT__PLUGIN_DIR . '/include/PayPalAuth.php');

			if (!PayPalAuth::isCredentialsValid()) {
				$error_message = "PayPal Client ID or Secret Key is invalid or the PayPal Mode is not compatible with the provided credentials.";
				wp_send_json_error(array('message' => $error_message));
			} else {
				require_once(WPGIFT__PLUGIN_DIR . '/vendor/autoload.php');
				require_once(WPGIFT__PLUGIN_DIR . '/include/PayPalAuth.php');

				$client = PayPalAuth::client();
				$request = new OrdersCreateRequest();
				$request->prefer('return=representation');
				// Resolve PayPal success page configured in settings (if any)
				$paypal_success_page_id = get_option('wpgv_giftvouchersuccesspage');
				if (!empty($paypal_success_page_id)) {
					$pp_page = get_post($paypal_success_page_id);
					if ($pp_page && $pp_page->post_status === 'publish') {
						$paypal_return_url = get_permalink($paypal_success_page_id) . '?voucheritem=' . $lastid;
					} else {
						$paypal_return_url = $success_url;
					}
				} else {
					$paypal_return_url = $success_url;
				}

				$request->body = [
					"intent" => "CAPTURE",
					"purchase_units" => [[
						"reference_id" => $template_voucher,
						"amount" => [
							"value" => $value,
							"currency_code" => $setting_options->currency_code
						]
					]],
					"application_context" => [
						"cancel_url" => $cancel_url,
						"return_url" => $paypal_return_url
					]
				];

				try {
					// Call API with your client and get a response for your call
					$response = $client->execute($request);
					// Normalize and persist the PayPal order id so it survives cross-site redirects
					$orderId = strval($response->result->id);
					if (session_status() == PHP_SESSION_NONE) {
						session_start();
					}
					$_SESSION["paypal_order_id"] = $orderId;
					// Persist to post meta so the success page can find the order id even if the session is lost
					if (!empty($lastid)) {
						update_post_meta($lastid, 'wpgv_paypal_order_id', sanitize_text_field($orderId));
						// Keep legacy meta key for compatibility
						update_post_meta($lastid, 'paypal_order_id', sanitize_text_field($orderId));
					}

					// Initialize an empty approve_link variable
					$approve_link = '';

					// If call returns body in response, you can get the deserialized version from the result attribute of the response
					foreach ($response->result->links as $link) {
						if ($link->rel == "approve") {
							$approve_link = $link->href;
						}
					}

					// Check if the approve_link is empty
					if (!empty($approve_link)) {
						wp_send_json_success(array('message' => "PayPal valid.", 'approve_link' => $approve_link));
					} else {
						wp_send_json_error(array('message' => "No PayPal approve link found."));
					}
				} catch (HttpException $ex) {
					// Log the exception for debugging (avoid printing raw exception to output)
					error_log('WPGV PayPal OrdersCreateRequest failed (voucher): ' . $ex->getMessage());
					wp_send_json_error(array('message' => 'PayPal request failed.'));
				}
			}
		}
	} elseif ($paymentmethod == 'Sofort') {

		$Sofortueberweisung = new Sofortueberweisung($setting_options->sofort_configure_key);

		$Sofortueberweisung->setAmount($value);
		$Sofortueberweisung->setCurrencyCode($setting_options->currency_code);

		$Sofortueberweisung->setReason($setting_options->reason_for_payment, $lastid);
		$Sofortueberweisung->setSuccessUrl($success_url, true);
		$Sofortueberweisung->setAbortUrl($cancel_url);
		// $Sofortueberweisung->setNotificationUrl($notify_url);

		$Sofortueberweisung->sendRequest();

		if ($Sofortueberweisung->isError()) {
			//SOFORT-API didn't accept the data
			// echo $Sofortueberweisung->getError();
			$error_message = "Sofort is invalid.";
			wp_send_json_error(array('message' => $error_message));
		} else {
			//buyer must be redirected to $paymentUrl else payment cannot be successfully completed!
			$paymentUrl = $Sofortueberweisung->getPaymentUrl();
			wp_send_json_success(array('message' => "Sofort valid.", 'approve_link' => $paymentUrl));
		}
	} elseif ($paymentmethod == 'Stripe') {

		$stripesuccesspageurl = get_option('wpgv_stripesuccesspage');

		// Resolve Stripe success permalink safely; fallback to default success path
		if (!empty($stripesuccesspageurl)) {
			$stripe_success_permalink = get_permalink($stripesuccesspageurl);
		} else {
			$stripe_success_permalink = get_home_url() . '/voucher-payment-successful/';
		}

		//set api key
		$stripe = array(
			"publishable_key" => $setting_options->stripe_publishable_key,
			"secret_key"      => $setting_options->stripe_secret_key,
		);

		$camount = ($value) * 100;
		$stripeemail = ($email) ? $email : $shipping_email;

		// Initialize Stripe using force loader function
		if (!wpgv_init_force_stripe($stripe['secret_key'])) {
			wp_send_json_error(array('message' => 'Failed to initialize Stripe.'));
			exit;
		}

		$is_stripe_ideal_enable = get_option('wpgv_stripe_ideal');

		// Prepare session data
		$session_data = [
			// 'payment_method_types' removed to allow Stripe to determine available methods
			'line_items' => [[
				'price_data' => [
					'currency' => $setting_options->currency_code,
					'unit_amount' => $camount,
					'product_data' => [
						'name' => $template_voucher,
					],
				],
				'quantity' => 1,
			]],
			'mode' => 'payment',
			'success_url' => $stripe_success_permalink . '?voucheritem=' . $lastid . '&sessionid={CHECKOUT_SESSION_ID}',
			'cancel_url' => $cancel_url,
		];

		// Create Stripe session using force loader function
		$result = wpgv_create_force_stripe_session($session_data);

		if ($result['success']) {
			$session = $result['data'];
			// Persist Stripe session id so webhook can map session -> voucher
			$session_id = is_object($session) ? ($session->id ?? '') : (is_array($session) ? ($session['id'] ?? '') : '');
			if (!empty($session_id) && $lastid) {
				update_post_meta($lastid, 'wpgv_stripe_session_key', sanitize_text_field($session_id));
			}
			$stripeemail = ($email) ? $email : $shipping_email;
			wp_send_json_success(array('message' => "Stripe valid.", 'approve_link' => $session->url));
		} else {
			wp_send_json_error(array('message' => $result['data']));
		}
	} elseif ($paymentmethod == 'MultiSafepay') {
		$wpgv_multisafepay_test_mode = get_option('wpgv_multisafepay_test_mode') ? get_option('wpgv_multisafepay_test_mode') : '';
		$wpgv_multisafepay_api_id = get_option('wpgv_multisafepay_api_id') ? get_option('wpgv_multisafepay_api_id') : '0ff28d5cc3a6e7475be5fa174703788fa155fc94';
		$msp_api_url = $wpgv_multisafepay_test_mode ? 'https://testapi.multisafepay.com/v1/json/' : 'https://api.multisafepay.com/v1/json/';
		$msp = new \MultiSafepayAPI\Client;
		$msp->setApiKey($wpgv_multisafepay_api_id);
		$msp->setApiUrl($msp_api_url);
		$camount = ($value) * 100;
		try {
			$order_id = $lastid;

			// Resolve MultiSafepay success page if configured
			$multisafepay_page_id = get_option('wpgv_multisafepaysuccesspage');
			if (!empty($multisafepay_page_id)) {
				$msp_page = get_post($multisafepay_page_id);
				$msp_base = ($msp_page && $msp_page->post_status === 'publish') ? get_permalink($multisafepay_page_id) : $success_url;
			} else {
				$msp_base = $success_url;
			}
			$msp_redirect_url = add_query_arg('voucheritem', $lastid, $msp_base);

			$order = $msp->orders->post(array(
				"type" => "redirect",
				"order_id" => $order_id,
				"currency" => $setting_options->currency_code,
				"amount" => $camount,
				"description" => $template_options->title,
				"payment_options" => array(
					"notification_url" => $notify_url,
					"redirect_url" => $msp_redirect_url,
					"cancel_url" => $cancel_url,
					"close_window" => "true"
				),
				"customer" => array(
					"ip_address" => $_SERVER['REMOTE_ADDR'],
					"forwarded_ip" => $_SERVER['REMOTE_ADDR'],
					"first_name" => $from,
					"email" => $email,
				),
			));

			wp_send_json_success(array('message' => "Per Invoice valid.", 'approve_link' => $msp->orders->getPaymentLink()));
		} catch (Exception $e) {
			wp_send_json_error(array('message' => "Error " . htmlspecialchars($e->getMessage())));
		}
	} elseif ($paymentmethod == 'Per Invoice') {
		// Resolve Per Invoice success page if configured in settings
		$perinvoice_page_id = get_option('wpgv_perinvoicesuccesspage');
		if (!empty($perinvoice_page_id)) {
			$perinvoice_page = get_post($perinvoice_page_id);
			$perinvoice_base = ($perinvoice_page && $perinvoice_page->post_status === 'publish') ? get_permalink($perinvoice_page_id) : $success_url;
		} else {
			$perinvoice_base = $success_url;
		}
		$perinvoice_url = add_query_arg(array('voucheritem' => $lastid, 'per_invoice' => '1'), $perinvoice_base);
		wp_send_json_success(array('message' => "Per Invoice valid.", 'approve_link' => $perinvoice_url));
	} elseif ($paymentmethod == 'Klarna') {
		// Klarna Payments v1 (Sessions API) - Modern integration
		$wpgv_klarna_enabled = get_option('wpgv_klarna') ? get_option('wpgv_klarna') : 0;
		if (!$wpgv_klarna_enabled) {
			wp_send_json_error(array('message' => 'Klarna is not enabled in settings.'));
		}
		$klarna_mode = get_option('wpgv_klarna_mode') ? get_option('wpgv_klarna_mode') : 'sandbox';
		if ($klarna_mode === 'live') {
			$merchant_id = get_option('wpgv_klarna_live_merchant_id');
			$shared_secret = get_option('wpgv_klarna_live_shared_secret');
			$klarna_sessions_url = 'https://api.klarna.com/payments/v1/sessions';
		} else {
			$merchant_id = get_option('wpgv_klarna_demo_merchant_id');
			$shared_secret = get_option('wpgv_klarna_demo_shared_secret');
			$klarna_sessions_url = 'https://api.playground.klarna.com/payments/v1/sessions';
		}
		if (empty($merchant_id) || empty($shared_secret)) {
			wp_send_json_error(array('message' => 'Klarna credentials are not configured.'));
		}

		// Amount in minor units (cents/øre)
		$amount_minor = intval(round(floatval($value) * 100));

		// Locale and country detection
		$klarna_purchase_override = get_option('wpgv_klarna_purchase_country');
		$locale_raw = function_exists('get_locale') ? get_locale() : 'en_US';
		$locale_key = str_replace('-', '_', $locale_raw);
		$locale_map = array(
			'de_AT' => array('locale' => 'de-AT', 'country' => 'AT'),
			'de_DE' => array('locale' => 'de-DE', 'country' => 'DE'),
			'en_GB' => array('locale' => 'en-GB', 'country' => 'GB'),
			'fr_FR' => array('locale' => 'fr-FR', 'country' => 'FR'),
			'nl_NL' => array('locale' => 'nl-NL', 'country' => 'NL'),
			'it_IT' => array('locale' => 'it-IT', 'country' => 'IT'),
			'es_ES' => array('locale' => 'es-ES', 'country' => 'ES'),
			'sv_SE' => array('locale' => 'sv-SE', 'country' => 'SE'),
			'fi_FI' => array('locale' => 'fi-FI', 'country' => 'FI'),
			'da_DK' => array('locale' => 'da-DK', 'country' => 'DK'),
			'nb_NO' => array('locale' => 'nb-NO', 'country' => 'NO'),
			'pl_PL' => array('locale' => 'pl-PL', 'country' => 'PL'),
			'pt_PT' => array('locale' => 'pt-PT', 'country' => 'PT'),
			'ro_RO' => array('locale' => 'ro-RO', 'country' => 'RO'),
			'cs_CZ' => array('locale' => 'cs-CZ', 'country' => 'CZ'),
			'sk_SK' => array('locale' => 'sk-SK', 'country' => 'SK'),
			'hu_HU' => array('locale' => 'hu-HU', 'country' => 'HU'),
			'bg_BG' => array('locale' => 'bg-BG', 'country' => 'BG'),
			'hr_HR' => array('locale' => 'hr-HR', 'country' => 'HR'),
			'lt_LT' => array('locale' => 'lt-LT', 'country' => 'LT'),
			'lv_LV' => array('locale' => 'lv-LV', 'country' => 'LV'),
			'sl_SI' => array('locale' => 'sl-SI', 'country' => 'SI'),
			'ee_EE' => array('locale' => 'et-EE', 'country' => 'EE'),
			'lu_LU' => array('locale' => 'fr-LU', 'country' => 'LU'),
			'mt_MT' => array('locale' => 'en-MT', 'country' => 'MT'),
			'cy_CY' => array('locale' => 'en-CY', 'country' => 'CY'),
		);
		// Country -> native language locale mapping for Klarna (when WP locale doesn't match)
		$country_locale_map = array(
			'SE' => 'sv-SE',
			'NO' => 'nb-NO',
			'DK' => 'da-DK',
			'FI' => 'fi-FI',
			'AT' => 'de-AT',
			'DE' => 'de-DE',
			'FR' => 'fr-FR',
			'IT' => 'it-IT',
			'ES' => 'es-ES',
			'NL' => 'nl-NL',
			'PL' => 'pl-PL',
			'PT' => 'pt-PT',
		);
		if (!empty($klarna_purchase_override)) {
			$override = trim($klarna_purchase_override);
			if (preg_match('/^[A-Za-z]{2}$/', $override)) {
				$purchase_country = strtoupper($override);
				// Use native language locale for country, or fallback to locale_raw language
				$klarna_locale = isset($country_locale_map[$purchase_country]) ? $country_locale_map[$purchase_country] : (strtolower(substr($locale_raw, 0, 2)) . '-' . $purchase_country);
			} else {
				$override_locale = str_replace('_', '-', $override);
				$klarna_locale = $override_locale;
				$parts = preg_split('/[-_]/', $override_locale);
				$purchase_country = isset($parts[1]) ? strtoupper($parts[1]) : strtoupper($override);
			}
		} else {
			if (isset($locale_map[$locale_key])) {
				$klarna_locale = $locale_map[$locale_key]['locale'];
				$purchase_country = $locale_map[$locale_key]['country'];
			} else {
				$parts = preg_split('/[_-]/', $locale_raw);
				if (count($parts) >= 2) {
					$purchase_country = strtoupper($parts[1]);
					// Use native language locale if available, else use WP locale's language
					$klarna_locale = isset($country_locale_map[$purchase_country]) ? $country_locale_map[$purchase_country] : (strtolower($parts[0]) . '-' . $purchase_country);
				} else {
					$klarna_locale = 'en-GB';
					$purchase_country = 'GB';
				}
			}
		}

		// Validate country/currency compatibility
		$country_currency_map = array(
			'AT' => 'EUR',
			'DE' => 'EUR',
			'NL' => 'EUR',
			'FR' => 'EUR',
			'IT' => 'EUR',
			'ES' => 'EUR',
			'SE' => 'SEK',
			'FI' => 'EUR',
			'DK' => 'DKK',
			'NO' => 'NOK',
			'GB' => 'GBP',
			'US' => 'USD',
		);
		$currency_upper = strtoupper($currency_code);
		if (isset($country_currency_map[$purchase_country]) && $currency_upper !== $country_currency_map[$purchase_country]) {
			wp_send_json_error(array('message' => sprintf("Klarna market '%s' requires currency '%s' but site is configured with '%s'. Change your Currency Code or set a matching Klarna Market Override.", $purchase_country, $country_currency_map[$purchase_country], $currency_upper)));
		}

		// Klarna Payments v1 Session payload
		// Per Klarna official docs: DO NOT include customer/billing/shipping in session (Step 1)
		// These belong ONLY in authorize() call (Step 2), not in session creation
		// Reference: https://docs.klarna.com/payments/web-payments/integrate-with-klarna-payments/integrate-via-sdk/step-1-initiate-a-payment/

		// Get configured Klarna success page - REQUIRED
		$klarna_success_page_id = get_option('wpgv_klarna_success_page');
		if (!$klarna_success_page_id || $klarna_success_page_id <= 0) {
			wp_send_json_error(array('message' => __('Klarna Success Page is not configured. Please go to Gift Voucher Pro Settings and select a Klarna Success Page.', 'gift-voucher')));
		}

		// Verify the page exists and is published
		$klarna_success_page = get_post($klarna_success_page_id);
		if (!$klarna_success_page || $klarna_success_page->post_status !== 'publish') {
			wp_send_json_error(array('message' => __('The configured Klarna Success Page does not exist or is not published. Please check your settings.', 'gift-voucher')));
		}

		// Verify the page contains the required shortcode
		if (strpos($klarna_success_page->post_content, '[wpgv_klarnasuccesspage]') === false) {
			wp_send_json_error(array('message' => __('The configured Klarna Success Page does not contain the [wpgv_klarnasuccesspage] shortcode. Please add the shortcode to the page.', 'gift-voucher')));
		}

		$base_success_url = get_permalink($klarna_success_page_id);
		$base_success_url = add_query_arg('voucheritem', $lastid, $base_success_url);

		// Ensure name is not empty and within Klarna limits (max 255 chars)
		$orderLineName = !empty($template_voucher) ? substr(sanitize_text_field($template_voucher), 0, 255) : 'Gift Voucher';

		$payload = array(
			'purchase_country' => $purchase_country,
			'purchase_currency' => $currency_upper,
			'locale' => $klarna_locale,
			'order_amount' => $amount_minor,
			'order_tax_amount' => 0,
			'order_lines' => array(array(
				'type' => 'digital',
				'reference' => 'voucher-' . $lastid,
				'name' => $orderLineName,
				'quantity' => 1,
				'unit_price' => $amount_minor,
				'tax_rate' => 0,
				'total_amount' => $amount_minor,
				'total_tax_amount' => 0,
				'total_discount_amount' => 0,
			)),
			'merchant_urls' => array(
				'terms' => get_site_url(),
				'checkout' => $base_success_url . '&session_id={session_id}',
				'confirmation' => $base_success_url,
				'push' => get_site_url() . '/wp-admin/admin-ajax.php?action=wpgv_klarna_push_notification',
			),
			'client' => array(
				'locale' => $klarna_locale,
			),
		);
		$json_body = wp_json_encode($payload);

		$args = array(
			'headers' => array(
				'Authorization' => 'Basic ' . base64_encode($merchant_id . ':' . $shared_secret),
				'Content-Type' => 'application/json'
			),
			'body' => $json_body,
			'timeout' => 30,
		);

		error_log('Klarna Payments v1 - Creating session for: ' . $orderLineName . ' - Amount: ' . $amount_minor . ' ' . $currency_upper);
		error_log('Klarna Payload: ' . $json_body);

		$response = wp_remote_post($klarna_sessions_url, $args);
		if (is_wp_error($response)) {
			wp_send_json_error(array('message' => 'Klarna API request failed: ' . $response->get_error_message()));
		}

		$code = wp_remote_retrieve_response_code($response);
		$body = wp_remote_retrieve_body($response);
		$data = json_decode($body, true);

		if ($code >= 200 && $code < 300) {
			// Store session data for later authorization
			// CRITICAL: Store the original $payload (what we sent), not $data (Klarna's response)
			// because we need order_lines, order_amount, etc. for create order step
			if (!empty($data['session_id'])) {
				update_post_meta($lastid, 'wpgv_klarna_session_id', sanitize_text_field($data['session_id']));
				update_post_meta($lastid, 'wpgv_klarna_session_data', wp_json_encode($payload));
			}

			// Return client_token to frontend for Klarna.js
			if (!empty($data['client_token'])) {
				$response_payload = array(
					'message' => 'Klarna session created.',
					'client_token' => $data['client_token'],
					'session_id' => $data['session_id'],
					'purchase_country' => $purchase_country,
					'purchase_currency' => $currency_upper,
				);
				// Include debug for admins
				if ((function_exists('current_user_can') && current_user_can('manage_options')) || (defined('WP_DEBUG') && WP_DEBUG)) {
					$response_payload['debug_payload'] = $payload;
					$response_payload['debug_klarna_response'] = $data;
				}
				wp_send_json_success($response_payload);
			} else {
				wp_send_json_error(array('message' => 'Klarna session created but no client_token returned.'));
			}
		} else {
			$error_msg = !empty($data['error_message']) ? $data['error_message'] : (!empty($data['error_code']) ? $data['error_code'] : $body);
			wp_send_json_error(array('message' => 'Klarna API error: ' . $error_msg));
		}
	} elseif ($paymentmethod == 'mollie') {

		require_once(WPGIFT__PLUGIN_DIR . '/vendor/autoload.php');
		$mollie_success_url = get_site_url() . '/mollie-payment-successful/?voucheritem=' . $lastid;

		$mollie_api_key = $setting_options->mollie_api_key;

		if (!$mollie_api_key) {
			wp_send_json_error(array('message' => "Mollie API key is missing."));
			exit;
		}

		try {
			$mollie = new Mollie\Api\MollieApiClient();
			$mollie->setApiKey($mollie_api_key);

			// Kiểm tra tài khoản đã được kích hoạt hay chưa
			$profile = $mollie->profiles->getCurrent();
			if (!$profile->status == 'active') {
				wp_send_json_error(array('message' => "Mollie account is not active."));
				exit;
			}

			$format_number_mollie = number_format($value, 2, '.', '');

			$description = !empty($template_options->title) ? $template_options->title : "Default payment description";
			if (strlen($description) > 191) {
				$description = substr($description, 0, 191);
			}

			$payment = $mollie->payments->create([
				"amount" => [
					"currency" => $setting_options->currency_code,
					"value" => $format_number_mollie
				],
				"description" => $description,
				"redirectUrl" => $mollie_success_url,
			]);
			if ($payment->id) {
				session_start();
				$_SESSION['payment_id'] = $payment->id;
			}

			wp_send_json_success(array('message' => "Mollie valid.", 'approve_link' => $payment->getCheckoutUrl()));
		} catch (Mollie\Api\Exceptions\ApiException $e) {
			wp_send_json_error(array('message' => "API call failed: " . htmlspecialchars($e->getMessage())));
		}
	}

	wp_die();
}
add_action('wp_ajax_nopriv_wpgv_doajax_voucher_pdf_save_func', 'wpgv__doajax_voucher_pdf_save_func');
add_action('wp_ajax_wpgv_doajax_voucher_pdf_save_func', 'wpgv__doajax_voucher_pdf_save_func');
