<?php
namespace PayCal\Gateway;

defined('ABSPATH') || exit;

use PayCal\Connector\ConnectorStore;

if (!class_exists('WC_Payment_Gateway')) {
  return;
}

add_action('template_redirect', function () {
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public WooCommerce return route; authenticated by order key and server-side PayCal verification below.
  if (!empty($_GET['wc-api']) && sanitize_key(wp_unslash($_GET['wc-api'])) === 'paycal_hosted_return') {
    return;
  }

  if (!WC_Gateway_PayCal_Hosted::is_paycal_return_request()) {
    return;
  }

  WC_Gateway_PayCal_Hosted::handle_return_request(false);
});

add_action('woocommerce_api_paycal_hosted_return', function () {
  WC_Gateway_PayCal_Hosted::handle_return_request(true);
});

add_filter('woocommerce_payment_complete_order_status', function ($status, $order_id, $order = null) {
  WC_Gateway_PayCal_Hosted::record_payment_complete_order_status_filter($order_id, $status);
  return $status;
}, 10, 3);

add_action('woocommerce_order_status_processing', function ($order_id, $order = null) {
  WC_Gateway_PayCal_Hosted::record_processing_status_hook($order_id);
}, 10, 2);

add_action('woocommerce_payment_complete', function ($order_id) {
  WC_Gateway_PayCal_Hosted::record_payment_complete_hook($order_id);
}, 10, 1);

class WC_Gateway_PayCal_Hosted extends \WC_Payment_Gateway {
  private static array $last_verification_response = [];
  private static array $payment_complete_order_status_filters = [];
  private static array $processing_status_hooks = [];
  private static array $payment_complete_hooks = [];

  public static function is_paycal_return_request(): bool {
    // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Public hosted checkout return; adding a nonce would change the PayCal return contract.
    $paid = isset($_GET['paycal_paid']) ? sanitize_text_field(wp_unslash($_GET['paycal_paid'])) : '';
    $order_id = isset($_GET['paycal_order_id']) ? absint(wp_unslash($_GET['paycal_order_id'])) : 0;
    $order_key = isset($_GET['paycal_order_key']) ? sanitize_text_field(wp_unslash($_GET['paycal_order_key'])) : '';
    // phpcs:enable WordPress.Security.NonceVerification.Recommended

    return $paid === '1' && $order_id > 0 && $order_key !== '';
  }

  public static function handle_return_request(bool $redirect_after): void {
    if (!self::is_paycal_return_request()) {
      return;
    }

  if (!function_exists('wc_get_order')) {
    return;
  }

  // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Return was identified above; order key and server verification protect the flow.
  $order_id = isset($_GET['paycal_order_id']) ? absint(wp_unslash($_GET['paycal_order_id'])) : 0;
  $order = wc_get_order($order_id);

  if (!$order) {
    \paycal_debug_log('[PayCal] WooCommerce return received for missing order ' . (string) $order_id . '.');
    return;
  }

  // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public hosted checkout return; validated against the WooCommerce order key.
  $order_key = isset($_GET['paycal_order_key']) ? sanitize_text_field(wp_unslash($_GET['paycal_order_key'])) : '';

  if (!hash_equals($order->get_order_key(), $order_key)) {
    \paycal_debug_log('[PayCal] WooCommerce return rejected because order key did not match for order ' . (string) $order->get_id() . '.');
    return;
  }

  $previous_status = method_exists($order, 'get_status') ? (string) $order->get_status() : '';
  $payment_complete_called = 'no';

  if (!$order->is_paid() && WC_Gateway_PayCal_Hosted::verify_order_payment($order)) {
    $payment_complete_called = 'yes';
    $order->payment_complete(WC_Gateway_PayCal_Hosted::last_verified_payment_id($order));
    WC_Gateway_PayCal_Hosted::add_payment_approval_note($order);
    $order->save();
    WC_Gateway_PayCal_Hosted::add_email_diagnostic_note($order, $previous_status, method_exists($order, 'get_status') ? (string) $order->get_status() : '', $payment_complete_called);
    \paycal_debug_log('[PayCal] WooCommerce return completed for order ' . (string) $order->get_id() . '.');
  } elseif (!$order->is_paid()) {
    WC_Gateway_PayCal_Hosted::add_failed_verification_note($order);
    \paycal_debug_log('[PayCal] WooCommerce return finished without confirmed payment for order ' . (string) $order->get_id() . '.');
  } else {
    WC_Gateway_PayCal_Hosted::add_email_diagnostic_note($order, $previous_status, method_exists($order, 'get_status') ? (string) $order->get_status() : '', $payment_complete_called);
  }

    if ($redirect_after && $order->is_paid()) {
      $redirect_debug = self::return_redirect_debug($order);
      $redirect_url = $redirect_debug['redirect_url'];
      \paycal_debug_log('[PayCal] Hosted return redirecting customer after verification. order_id=' . (string) $order->get_id() . ', redirect_url=' . $redirect_url . ', has_key=' . (strpos($redirect_url, 'key=') !== false ? 'yes' : 'no'));
      self::render_success_transition($redirect_url, $order, $redirect_debug);
    } elseif ($redirect_after) {
      self::render_failed_return_response();
    }
  }

  public function __construct() {
    $this->id = 'paycal_hosted';
    $this->icon = '';
    $this->has_fields = false;
    $this->method_title = 'PayCal Hosted Checkout';
    $this->method_description = 'Redirect-based hosted checkout through PayCal Platform. Apple Pay is provisioned per merchant/terminal in PayCal.';
    $this->supports = ['products'];

    $this->init_form_fields();
    $this->init_settings();

    $this->title = $this->get_option('title', 'Apple Pay / Credit Card');
    $this->description = $this->get_option('description', 'Secure payment through PayCal.');
    $this->enabled = $this->get_option('enabled', 'no');

    add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']);
  }

  public function init_form_fields(): void {
    $this->form_fields = [
      'enabled' => [
        'title' => 'Enable/Disable',
        'type' => 'checkbox',
        'label' => 'Enable PayCal Hosted Checkout',
        'default' => 'no',
      ],
      'title' => [
        'title' => 'Title',
        'type' => 'text',
        'default' => 'Apple Pay / Credit Card',
      ],
      'description' => [
        'title' => 'Customer Description',
        'type' => 'textarea',
        'default' => 'Secure payment through PayCal.',
      ],
      'checkout_path' => [
        'title' => 'Hosted Checkout Path',
        'type' => 'text',
        'default' => '/checkout/',
        'description' => 'Relative hosted checkout path on the PayCal Platform. The customer plugin never stores Apple Pay secrets.',
      ],
    ];
  }

  public function is_available() {
    if ('yes' !== $this->enabled) {
      return false;
    }

    if (!class_exists(ConnectorStore::class)) {
      return false;
    }

    $settings = ConnectorStore::get();

    if (empty($settings['platform_url']) || empty($settings['merchant_id']) || empty($settings['public_key'])) {
      return false;
    }

    return parent::is_available();
  }

  public function process_payment($order_id) {
    $order = wc_get_order($order_id);

    if (!$order) {
      wc_add_notice('Payment error: order not found.', 'error');
      return ['result' => 'failure'];
    }

    $settings = ConnectorStore::get();
    $checkout_url = '';
    if (($settings['use_checkout_sessions'] ?? 'no') === 'yes') {
      $checkout_url = $this->create_checkout_session($order, $settings);
    }
    if ($checkout_url === '') {
      $checkout_url = $this->build_checkout_url($order, $settings);
    }

    $order->update_status('pending', 'PayCal hosted checkout opened.');
    $order->save();

    return [
      'result' => 'success',
      'redirect' => $checkout_url,
    ];
  }

  public static function verify_order_payment($order): bool {
    if (!is_object($order) || !method_exists($order, 'get_id')) {
      \paycal_debug_log('[PayCal] Payment verification skipped: invalid WooCommerce order object.');
      return false;
    }

    \paycal_debug_log('[PayCal] Server verification started for order ' . (string) $order->get_id() . '.');

    if (!class_exists(ConnectorStore::class)) {
      \paycal_debug_log('[PayCal] Payment verification failed: connector settings store unavailable for order ' . (string) $order->get_id() . '.');
      return false;
    }

    $settings = ConnectorStore::get();
    if (empty($settings['platform_url']) || empty($settings['public_key']) || empty($settings['access_token']) || empty($settings['merchant_id'])) {
      \paycal_debug_log('[PayCal] Payment verification failed: connector credentials incomplete for order ' . (string) $order->get_id() . '.');
      return false;
    }

    if (!function_exists('wp_remote_post')) {
      \paycal_debug_log('[PayCal] Payment verification failed: WordPress HTTP API unavailable.');
      return false;
    }

    $session_id = self::latest_checkout_session_id_from_notes($order);
    $response = wp_remote_post(rtrim((string) $settings['platform_url'], '/') . '/wp-json/paycal/v1/payments/verify', [
      'timeout' => 15,
      'headers' => [
        'Content-Type' => 'application/json',
        'X-PayCal-Public-Key' => (string) $settings['public_key'],
        'X-PayCal-Token' => (string) $settings['access_token'],
      ],
      'body' => wp_json_encode([
        'merchant_id' => (string) $settings['merchant_id'],
        'terminal_id' => (string) ($settings['terminal_id'] ?? ''),
        'order_id' => (string) $order->get_id(),
        'amount' => (string) $order->get_total(),
        'currency' => (string) $order->get_currency(),
        'site_url' => home_url('/'),
        'session_id' => $session_id,
      ]),
    ]);

    if (is_wp_error($response)) {
      \paycal_debug_log('[PayCal] Payment verification failed: ' . $response->get_error_message());
      return false;
    }

    $code = wp_remote_retrieve_response_code($response);
    $raw = wp_remote_retrieve_body($response);
    $body = json_decode($raw, true);
    $paid = $code >= 200 && $code < 300 && is_array($body) && !empty($body['paid']);
    self::$last_verification_response[(int) $order->get_id()] = is_array($body) ? $body : [];
    if ($paid && !self::verification_response_matches_order($body, $order, $session_id)) {
      $paid = false;
      \paycal_debug_log('[PayCal] Server verification response mismatch for order ' . (string) $order->get_id() . '. HTTP ' . (int) $code . ', body_hash=' . hash('sha256', (string) $raw));
    }

    if (!$paid) {
      \paycal_debug_log('[PayCal] Server verification failed for order ' . (string) $order->get_id() . '. HTTP ' . (int) $code . ', body_hash=' . hash('sha256', (string) $raw));
      return false;
    }

    \paycal_debug_log('[PayCal] Server verification succeeded for order ' . (string) $order->get_id() . '.');
    return true;
  }

  public static function add_failed_verification_note($order): void {
    if (!is_object($order) || !method_exists($order, 'get_id')) {
      return;
    }
    if (self::order_has_failed_verification_note($order)) {
      return;
    }
    $verification = self::$last_verification_response[(int) $order->get_id()] ?? [];
    $code = is_array($verification) ? self::scalar_text($verification['code'] ?? '') : '';
    $order->add_order_note($code === 'checkout_session_expired' ? 'PayCal session expired.' : 'PayCal verification failed.');
  }

  public static function record_payment_complete_order_status_filter($order_id, $status): void {
    $order_id = absint($order_id);
    if ($order_id <= 0 || !self::is_paycal_hosted_order_id($order_id)) {
      return;
    }

    self::$payment_complete_order_status_filters[$order_id] = self::scalar_text($status);
  }

  public static function record_processing_status_hook($order_id): void {
    $order_id = absint($order_id);
    if ($order_id <= 0 || !self::is_paycal_hosted_order_id($order_id)) {
      return;
    }

    self::$processing_status_hooks[$order_id] = true;
  }

  public static function record_payment_complete_hook($order_id): void {
    $order_id = absint($order_id);
    if ($order_id <= 0 || !self::is_paycal_hosted_order_id($order_id)) {
      return;
    }

    self::$payment_complete_hooks[$order_id] = true;
  }

  public static function add_email_diagnostic_note($order, string $previous_status, string $new_status, string $payment_complete_called): void {
    if (!is_object($order) || !method_exists($order, 'get_id') || self::order_has_email_diagnostic_note($order)) {
      return;
    }

    $order_id = (int) $order->get_id();
    $billing_email = method_exists($order, 'get_billing_email') ? self::scalar_text($order->get_billing_email()) : '';
    $mailer_available = 'no';
    $processing_email_enabled = 'unknown';

    if (function_exists('WC')) {
      try {
        $wc = WC();
        if (is_object($wc) && method_exists($wc, 'mailer')) {
          $mailer = $wc->mailer();
          $mailer_available = is_object($mailer) ? 'yes' : 'no';
          if (is_object($mailer) && method_exists($mailer, 'get_emails')) {
            $emails = $mailer->get_emails();
            if (isset($emails['WC_Email_Customer_Processing_Order']) && is_object($emails['WC_Email_Customer_Processing_Order']) && method_exists($emails['WC_Email_Customer_Processing_Order'], 'is_enabled')) {
              $processing_email_enabled = $emails['WC_Email_Customer_Processing_Order']->is_enabled() ? 'yes' : 'no';
            }
          }
        }
      } catch (\Throwable $e) {
        $mailer_available = 'error';
      }
    }

    $lines = [
      'PayCal WooCommerce email diagnostics.',
      'Previous status before payment_complete: ' . ($previous_status !== '' ? $previous_status : 'unknown'),
      'New status after payment_complete: ' . ($new_status !== '' ? $new_status : 'unknown'),
      'payment_complete called: ' . $payment_complete_called,
      'woocommerce_payment_complete hook seen: ' . (!empty(self::$payment_complete_hooks[$order_id]) ? 'yes' : 'no'),
      'payment_complete_order_status hook seen: ' . (isset(self::$payment_complete_order_status_filters[$order_id]) ? 'yes' : 'no'),
      'payment_complete_order_status result: ' . (self::$payment_complete_order_status_filters[$order_id] ?? 'not_seen'),
      'woocommerce_order_status_processing hook seen: ' . (!empty(self::$processing_status_hooks[$order_id]) ? 'yes' : 'no'),
      'WooCommerce mailer available: ' . $mailer_available,
      'Customer processing email enabled: ' . $processing_email_enabled,
      'Customer billing email exists: ' . ($billing_email !== '' ? 'yes' : 'no'),
    ];

    $order->add_order_note(implode("\n", $lines));
  }

  private static function is_paycal_hosted_order_id(int $order_id): bool {
    if (!function_exists('wc_get_order')) {
      return false;
    }

    $order = wc_get_order($order_id);
    return is_object($order) && method_exists($order, 'get_payment_method') && $order->get_payment_method() === 'paycal_hosted';
  }

  private static function order_has_email_diagnostic_note($order): bool {
    if (!function_exists('wc_get_order_notes')) {
      return false;
    }

    $notes = wc_get_order_notes([
      'order_id' => (int) $order->get_id(),
      'type' => 'internal',
      'limit' => 20,
    ]);
    foreach ((array) $notes as $note) {
      $content = is_object($note) && isset($note->content) ? (string) $note->content : '';
      if (strpos($content, 'PayCal WooCommerce email diagnostics.') !== false) {
        return true;
      }
    }
    return false;
  }

  public static function add_payment_approval_note($order): void {
    if (!is_object($order) || !method_exists($order, 'get_id')) {
      return;
    }

    $verification = self::$last_verification_response[(int) $order->get_id()] ?? [];
    if (!is_array($verification)) {
      $verification = [];
    }

    $payment_id = self::scalar_text($verification['payment_id'] ?? '');
    if ($payment_id !== '' && self::order_has_paycal_approval_note($order, $payment_id)) {
      return;
    }

    $lines = ['PayCal payment verified successfully.', 'Gateway: Apple Pay'];
    $amount = self::scalar_text($verification['amount'] ?? '');
    $currency = self::scalar_text($verification['currency'] ?? $order->get_currency());
    if ($amount !== '') {
      $lines[] = 'Amount: ' . self::format_paycal_amount($amount, $currency);
    }
    if ($payment_id !== '') {
      $lines[] = 'Payment ID: ' . $payment_id;
    }

    $session_id = self::latest_checkout_session_id_from_notes($order);
    if ($session_id !== '') {
      $lines[] = 'Session ID: ' . $session_id;
    }

    $verification_status = self::scalar_text($verification['verification'] ?? '');
    if ($verification_status !== '') {
      $lines[] = 'Verification: ' . $verification_status;
    }

    $payment_status = self::scalar_text($verification['status'] ?? '');
    if ($payment_status !== '') {
      $lines[] = 'Payment status: ' . $payment_status;
    }

    $order->add_order_note(implode("\n", $lines));
  }

  public static function last_verified_payment_id($order): string {
    if (!is_object($order) || !method_exists($order, 'get_id')) {
      return '';
    }

    $verification = self::$last_verification_response[(int) $order->get_id()] ?? [];
    return is_array($verification) ? self::scalar_text($verification['payment_id'] ?? '') : '';
  }

  private static function order_has_paycal_approval_note($order, string $payment_id): bool {
    if (!function_exists('wc_get_order_notes')) {
      return false;
    }

    $notes = wc_get_order_notes([
      'order_id' => (int) $order->get_id(),
      'type' => 'internal',
      'limit' => 20,
    ]);
    foreach ((array) $notes as $note) {
      $content = is_object($note) && isset($note->content) ? (string) $note->content : '';
      if ((strpos($content, 'PayCal payment verified successfully.') !== false || strpos($content, 'PayCal payment approved.') !== false) && strpos($content, $payment_id) !== false) {
        return true;
      }
    }
    return false;
  }

  private static function order_has_failed_verification_note($order): bool {
    if (!function_exists('wc_get_order_notes')) {
      return false;
    }

    $notes = wc_get_order_notes([
      'order_id' => (int) $order->get_id(),
      'type' => 'internal',
      'limit' => 20,
    ]);
    foreach ((array) $notes as $note) {
      $content = is_object($note) && isset($note->content) ? (string) $note->content : '';
      if (strpos($content, 'PayCal verification failed.') !== false || strpos($content, 'PayCal session expired.') !== false || strpos($content, 'PayCal hosted checkout return received, but server-to-server verification did not confirm payment.') !== false) {
        return true;
      }
    }
    return false;
  }

  private static function latest_checkout_session_id_from_notes($order): string {
    if (!function_exists('wc_get_order_notes')) {
      return '';
    }

    $notes = wc_get_order_notes([
      'order_id' => (int) $order->get_id(),
      'type' => 'internal',
      'limit' => 20,
    ]);
    foreach ((array) $notes as $note) {
      $content = is_object($note) && isset($note->content) ? (string) $note->content : '';
      if (preg_match('/PayCal generic checkout session created:\s*(pcs_[a-z0-9_-]{20,64})/i', $content, $matches)) {
        return sanitize_text_field($matches[1]);
      }
    }
    return '';
  }

  private static function format_paycal_amount(string $amount, string $currency): string {
    $formatted = number_format((float) $amount, 2, '.', '');
    $currency = strtoupper(sanitize_text_field($currency));
    if ($currency === 'ILS') {
      return '₪' . $formatted . ' ILS';
    }
    return $formatted . ($currency !== '' ? ' ' . $currency : '');
  }

  private static function scalar_text($value): string {
    return is_scalar($value) ? sanitize_text_field((string) $value) : '';
  }

  private static function verification_response_matches_order(array $body, $order, string $session_id): bool {
    $response_order_id = self::scalar_text($body['order_id'] ?? '');
    $response_amount = self::scalar_text($body['amount'] ?? '');
    $response_currency = strtoupper(self::scalar_text($body['currency'] ?? ''));
    $response_session_id = self::scalar_text($body['session_id'] ?? '');

    if ($response_order_id === '' || !hash_equals((string) $order->get_id(), $response_order_id)) {
      return false;
    }
    if ($response_amount === '' || abs((float) $response_amount - (float) $order->get_total()) >= 0.0001) {
      return false;
    }
    if ($response_currency === '' || !hash_equals(strtoupper((string) $order->get_currency()), $response_currency)) {
      return false;
    }
    if ($session_id !== '' && !hash_equals($session_id, $response_session_id)) {
      return false;
    }

    return true;
  }

  private static function clean_order_return_url($order): string {
    $debug = self::return_redirect_debug($order);
    return $debug['redirect_url'];
  }

  private static function return_redirect_debug($order): array {
    $debug = [
      'redirect_url' => wc_get_checkout_url(),
      'has_order_key' => 'no',
      'return_source' => 'checkout_fallback',
      'response_mode' => 'final_confirmation_page',
      'order_received_url' => '',
      'gateway_return_url' => '',
    ];

    if (!is_object($order)) {
      return $debug;
    }

    if (function_exists('wc_get_endpoint_url') && function_exists('wc_get_checkout_url') && method_exists($order, 'get_id') && method_exists($order, 'get_order_key')) {
      $order_received_url = wc_get_endpoint_url('order-received', (int) $order->get_id(), wc_get_checkout_url());
      $order_received_url = add_query_arg('key', $order->get_order_key(), $order_received_url);
      $debug['order_received_url'] = $order_received_url;
      $debug['redirect_url'] = $order_received_url;
      $debug['return_source'] = 'direct_order_received_url';
    }

    $debug['has_order_key'] = strpos($debug['redirect_url'], 'key=') !== false ? 'yes' : 'no';
    return $debug;
  }

  private static function add_return_redirect_debug_note($order, array $debug): void {
    if (!is_object($order) || !method_exists($order, 'add_order_note') || self::order_has_return_redirect_debug_note($order)) {
      return;
    }

    $lines = [
      'PayCal hosted return redirect debug.',
      'Redirect URL: ' . self::scalar_text($debug['redirect_url'] ?? ''),
      'Has order key: ' . self::scalar_text($debug['has_order_key'] ?? 'no'),
      'Return source: ' . self::scalar_text($debug['return_source'] ?? 'checkout_fallback'),
      'Response mode: ' . self::scalar_text($debug['response_mode'] ?? 'final_confirmation_page'),
      'Headers had Location before cleanup: ' . self::scalar_text($debug['headers_location_before_cleanup'] ?? 'unknown'),
      'Location header after cleanup: ' . self::scalar_text($debug['headers_location_after_cleanup'] ?? 'unknown'),
      'Output buffer level before cleanup: ' . self::scalar_text($debug['output_buffer_level_before_cleanup'] ?? 'unknown'),
      'Final response emitted: ' . self::scalar_text($debug['final_response_emitted'] ?? 'unknown'),
    ];

    $order_received_url = self::scalar_text($debug['order_received_url'] ?? '');
    if ($order_received_url !== '') {
      $lines[] = 'Order received URL: ' . $order_received_url;
    }

    $gateway_return_url = self::scalar_text($debug['gateway_return_url'] ?? '');
    if ($gateway_return_url !== '') {
      $lines[] = 'Gateway return URL: ' . $gateway_return_url;
    }

    $order->add_order_note(implode("\n", $lines));
  }

  private static function order_has_return_redirect_debug_note($order): bool {
    if (!function_exists('wc_get_order_notes')) {
      return false;
    }

    $notes = wc_get_order_notes([
      'order_id' => (int) $order->get_id(),
      'type' => 'internal',
      'limit' => 20,
    ]);
    foreach ((array) $notes as $note) {
      $content = is_object($note) && isset($note->content) ? (string) $note->content : '';
      if (strpos($content, 'PayCal hosted return redirect debug.') !== false) {
        return true;
      }
    }
    return false;
  }

  private static function render_failed_return_response(): void {
    if (function_exists('nocache_headers')) {
      nocache_headers();
    }
    if (!headers_sent()) {
      if (function_exists('status_header')) {
        status_header(403);
      }
      if (function_exists('header_remove')) {
        header_remove('Location');
      }
      header('Content-Type: text/html; charset=utf-8');
      header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
      header('Pragma: no-cache');
      header('Expires: Wed, 11 Jan 1984 05:00:00 GMT');
    }

    echo '<!doctype html><html lang="he" dir="rtl"><head><meta charset="utf-8">';
    echo '<meta name="viewport" content="width=device-width, initial-scale=1">';
    echo '<meta name="robots" content="noindex,nofollow">';
    echo '<title>' . esc_html__('Payment could not be confirmed', 'klamra-paycal-for-aspaclaria') . '</title>';
    echo '<style>body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;font-family:Arial,sans-serif;background:#f8fafc;color:#111827;text-align:center}.paycal-return{padding:28px;max-width:480px}.paycal-return h1{font-size:28px;margin:0 0 12px}.paycal-return p{font-size:17px;margin:0 0 18px;line-height:1.55}.paycal-return a{display:inline-block;margin-top:8px;padding:12px 18px;border-radius:10px;background:#0f766e;color:#fff;text-decoration:none;font-weight:700}</style>';
    echo '</head><body><main class="paycal-return">';
    echo '<h1>' . esc_html__('Payment could not be confirmed', 'klamra-paycal-for-aspaclaria') . '</h1>';
    echo '<p>' . esc_html__('Please contact the store if your payment was completed.', 'klamra-paycal-for-aspaclaria') . '</p>';
    echo '<p><a href="' . esc_url(function_exists('wc_get_checkout_url') ? wc_get_checkout_url() : home_url('/')) . '">' . esc_html__('Return to checkout', 'klamra-paycal-for-aspaclaria') . '</a></p>';
    echo '</main></body></html>';
    exit;
  }

  private static function render_success_transition(string $redirect_url, $order = null, array $debug = []): void {
    $redirect_url = esc_url_raw($redirect_url);
    $order_number = '';
    if (is_object($order) && method_exists($order, 'get_order_number')) {
      $order_number = self::scalar_text($order->get_order_number());
    }
    $store_url = function_exists('home_url') ? home_url('/') : '/';

    $buffer_level_before = function_exists('ob_get_level') ? (int) ob_get_level() : 0;
    $location_before_cleanup = self::headers_have_location() ? 'yes' : 'no';

    if (!headers_sent() && function_exists('ob_get_level') && function_exists('ob_get_status')) {
      while (ob_get_level() > 0) {
        $status = ob_get_status();
        if (empty($status['del'])) {
          break;
        }
        if (!@ob_end_clean()) {
          break;
        }
      }
    }

    if (function_exists('nocache_headers')) {
      nocache_headers();
    }
    if (!headers_sent()) {
      if (function_exists('status_header')) {
        status_header(200);
      }
      if (function_exists('header_remove')) {
        header_remove('Location');
      }
      header('Content-Type: text/html; charset=utf-8');
      header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
      header('Pragma: no-cache');
      header('Expires: Wed, 11 Jan 1984 05:00:00 GMT');
    }

    $debug['response_mode'] = 'final_confirmation_page';
    $debug['headers_location_before_cleanup'] = $location_before_cleanup;
    $debug['headers_location_after_cleanup'] = self::headers_have_location() ? 'yes' : 'no';
    $debug['output_buffer_level_before_cleanup'] = (string) $buffer_level_before;
    $debug['final_response_emitted'] = 'yes';
    self::add_return_redirect_debug_note($order, $debug);

    echo '<!doctype html><html lang="he" dir="rtl"><head><meta charset="utf-8">';
    echo '<meta name="viewport" content="width=device-width, initial-scale=1">';
    echo '<meta name="robots" content="noindex,nofollow">';
    echo '<title>' . esc_html__('התשלום אושר', 'klamra-paycal-for-aspaclaria') . '</title>';
    echo '<style>body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;font-family:Arial,sans-serif;background:#f8fafc;color:#111827;text-align:center}.paycal-return{padding:28px;max-width:480px}.paycal-return h1{font-size:30px;margin:0 0 10px}.paycal-return p{font-size:17px;margin:0 0 16px;line-height:1.55}.paycal-order-number{font-size:18px;font-weight:700;color:#0f172a}.paycal-primary-cta + .paycal-order-number + p{display:none}.paycal-return a{display:inline-block;margin-top:8px;padding:12px 18px;border-radius:10px;background:#0f766e;color:#fff;text-decoration:none;font-weight:700}.paycal-return small{display:block;margin-top:16px;color:#64748b}</style>';
    echo '</head><body><main class="paycal-return">';
    echo '<h1>' . esc_html__('התשלום אושר', 'klamra-paycal-for-aspaclaria') . '</h1>';
    echo '<p>' . esc_html__('ההזמנה התקבלה', 'klamra-paycal-for-aspaclaria') . '</p>';
    if ($order_number !== '') {
      echo '<p class="paycal-primary-cta"><a href="' . esc_url($store_url) . '">' . esc_html__('חזרה לחנות', 'klamra-paycal-for-aspaclaria') . '</a></p>';
      echo '<p class="paycal-order-number">' . esc_html__('מספר הזמנה: #', 'klamra-paycal-for-aspaclaria') . esc_html($order_number) . '</p>';
    }
    echo '<p><a href="' . esc_url($redirect_url) . '">' . esc_html__('צפייה בפרטי ההזמנה', 'klamra-paycal-for-aspaclaria') . '</a></p>';
    echo '<small>' . esc_html__('אישור ההזמנה נשלח לאימייל שלך.', 'klamra-paycal-for-aspaclaria') . '</small>';
    echo '</main></body></html>';
    exit;

    echo '<!doctype html><html lang="he" dir="rtl"><head><meta charset="utf-8">';
    echo '<meta name="viewport" content="width=device-width, initial-scale=1">';
    echo '<meta name="robots" content="noindex,nofollow">';
    echo '<title>' . esc_html__('התשלום אושר', 'klamra-paycal-for-aspaclaria') . '</title>';
    echo '<style>body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;font-family:Arial,sans-serif;background:#f8fafc;color:#111827;text-align:center}.paycal-return{padding:28px;max-width:440px}.paycal-return h1{font-size:28px;margin:0 0 12px}.paycal-return p{font-size:17px;margin:0 0 18px}.paycal-return a{color:#0f766e;font-weight:700}</style>';
    echo '</head><body><main class="paycal-return">';
    echo '<h1>' . esc_html__('התשלום אושר', 'klamra-paycal-for-aspaclaria') . '</h1>';
    echo '<p>' . esc_html__('מעבירים אותך לאישור ההזמנה...', 'klamra-paycal-for-aspaclaria') . '</p>';
    echo '<p><a href="' . esc_url($redirect_url) . '">' . esc_html__('המשך לאישור ההזמנה', 'klamra-paycal-for-aspaclaria') . '</a></p>';
    echo '</main></body></html>';
  }

  private static function headers_have_location(): bool {
    if (!function_exists('headers_list')) {
      return false;
    }

    foreach (headers_list() as $header) {
      if (stripos((string) $header, 'Location:') === 0) {
        return true;
      }
    }

    return false;
  }

  private function build_checkout_url($order, array $settings): string {
    $platform = rtrim((string) ($settings['checkout_base_url'] ?? $settings['platform_url']), '/');
    $path = '/' . ltrim((string) $this->get_option('checkout_path', '/checkout/'), '/');

    $return_url = add_query_arg([
      'wc-api' => 'paycal_hosted_return',
      'paycal_paid' => '1',
      'paycal_order_id' => $order->get_id(),
      'paycal_order_key' => $order->get_order_key(),
    ], home_url('/'));

    $payload = [
      'merchant_id' => (string) $settings['merchant_id'],
      'terminal_id' => (string) ($settings['terminal_id'] ?? ''),
      'public_key' => (string) $settings['public_key'],
      'order_id' => (string) $order->get_id(),
      'order_key' => (string) $order->get_order_key(),
      'amount' => (string) $order->get_total(),
      'currency' => (string) $order->get_currency(),
      'return_url' => $return_url,
      'cancel_url' => wc_get_checkout_url(),
      'site_url' => home_url('/'),
    ];

    $query = http_build_query($payload, '', '&', PHP_QUERY_RFC3986);

    return esc_url_raw($platform . $path . '?' . $query);
  }

  private function create_checkout_session($order, array $settings): string {
    if (!function_exists('wp_remote_post') || empty($settings['platform_url']) || empty($settings['public_key']) || empty($settings['access_token'])) {
      \paycal_debug_log('[PayCal] Generic checkout session skipped: connector API settings are incomplete.');
      return '';
    }

    $return_url = add_query_arg([
      'paycal_paid' => '1',
      'paycal_order_id' => $order->get_id(),
      'paycal_order_key' => $order->get_order_key(),
    ], $this->get_return_url($order));

    $response = wp_remote_post(rtrim((string) $settings['platform_url'], '/') . '/wp-json/paycal/v1/checkout-sessions/create', [
      'timeout' => 15,
      'headers' => [
        'Content-Type' => 'application/json',
        'X-PayCal-Public-Key' => (string) $settings['public_key'],
        'X-PayCal-Token' => (string) $settings['access_token'],
      ],
      'body' => wp_json_encode([
        'merchant_id' => (string) ($settings['merchant_id'] ?? ''),
        'terminal_id' => (string) ($settings['terminal_id'] ?? ''),
        'order_id' => (string) $order->get_id(),
        'order_key' => (string) $order->get_order_key(),
        'amount' => (string) $order->get_total(),
        'currency' => (string) $order->get_currency(),
        'return_url' => $return_url,
        'cancel_url' => wc_get_checkout_url(),
        'customer_email' => (string) $order->get_billing_email(),
        'site_url' => home_url('/'),
      ]),
    ]);

    if (is_wp_error($response)) {
      $error_code = sanitize_text_field((string) $response->get_error_code());
      $error_message = sanitize_text_field((string) $response->get_error_message());
      $diagnostic = 'transport_error=yes, error_code=' . ($error_code ?: 'unknown') . ', message=' . ($error_message ?: 'unknown');
      \paycal_debug_log('[PayCal] Generic checkout session creation failed. ' . $diagnostic);
      $order->add_order_note('PayCal generic checkout session create failed. ' . $diagnostic . '. Existing hosted checkout fallback used.');
      return '';
    }

    $code = wp_remote_retrieve_response_code($response);
    $raw = wp_remote_retrieve_body($response);
    $body = json_decode($raw, true);
    $valid_json = json_last_error() === JSON_ERROR_NONE && is_array($body);
    $session_id = is_array($body) ? sanitize_text_field((string) ($body['session_id'] ?? '')) : '';
    $checkout_url = is_array($body) ? esc_url_raw((string) ($body['checkout_url'] ?? '')) : '';
    $checkout_host = strtolower((string) wp_parse_url($checkout_url, PHP_URL_HOST));
    $checkout_scheme = strtolower((string) wp_parse_url($checkout_url, PHP_URL_SCHEME));

    if ($code < 200 || $code >= 300 || empty($body['ok']) || !preg_match('/^pcs_[a-z0-9_-]{20,64}$/', $session_id) || $checkout_scheme !== 'https' || $checkout_host !== 'checkout.paycal.online') {
      $diagnostic = $this->checkout_session_response_diagnostic((int) $code, $body, $valid_json, $session_id, $checkout_url);
      \paycal_debug_log('[PayCal] Generic checkout session creation returned an invalid response. ' . $diagnostic . ', body_hash=' . hash('sha256', (string) $raw));
      $order->add_order_note('PayCal generic checkout session create failed. ' . $diagnostic . '. Existing hosted checkout fallback used.');
      return '';
    }

    $order->add_order_note('PayCal generic checkout session created: ' . $session_id);
    \paycal_debug_log('[PayCal] Generic checkout session created for order ' . (string) $order->get_id() . ': ' . $session_id);
    return $checkout_url;
  }

  private function checkout_session_response_diagnostic(int $http_code, $body, bool $valid_json, string $session_id, string $checkout_url): string {
    $keys = $valid_json ? array_slice(array_map('sanitize_key', array_keys($body)), 0, 12) : [];
    $error_value = $valid_json ? ($body['code'] ?? ($body['error'] ?? '')) : '';
    $message_value = $valid_json ? ($body['message'] ?? '') : '';
    $error_code = is_scalar($error_value) ? sanitize_text_field((string) $error_value) : '';
    $message = is_scalar($message_value) ? sanitize_text_field((string) $message_value) : '';
    $data_status = $valid_json && isset($body['data']['status']) && is_scalar($body['data']['status']) ? absint($body['data']['status']) : 0;

    return implode(', ', [
      'http_status=' . $http_code,
      'valid_json=' . ($valid_json ? 'yes' : 'no'),
      'top_level_keys=' . ($keys ? implode('|', $keys) : 'none'),
      'error_code=' . ($error_code !== '' ? substr($error_code, 0, 80) : 'none'),
      'message=' . ($message !== '' ? substr($message, 0, 160) : 'none'),
      'data_status=' . ($data_status ?: 'none'),
      'session_id_exists=' . ($session_id !== '' ? 'yes' : 'no'),
      'checkout_url_exists=' . ($checkout_url !== '' ? 'yes' : 'no'),
    ]);
  }
}
