/**
 * Card Oracle Stripe Payment Processing
 *
 * Uses Stripe.js v3 with PaymentIntents API for SCA compliance and 3D Secure support.
 *
 * @package Card_Oracle
 * @since 1.2.1
 */

(function ($) {
  "use strict";

  // Stripe objects - initialized only when form is present.
  var stripe = null;
  var elements = null;
  var cardElement = null;
  var cardMounted = false;

  // Custom styling for the Stripe Element.
  var style = {
    base: {
      color: "#32325d",
      fontFamily:
        '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif',
      fontSmoothing: "antialiased",
      fontSize: "16px",
      "::placeholder": {
        color: "#aab7c4",
      },
    },
    invalid: {
      color: "#dc3545",
      iconColor: "#dc3545",
    },
  };

  /**
   * Initialize Stripe and create the card element.
   */
  function initializeStripe() {
    // Check if Stripe.js is loaded.
    if (typeof Stripe === "undefined") {
      console.error("Card Oracle: Stripe.js not loaded");
      return false;
    }

    // Check if we have the publishable key.
    if (!stripe_vars || !stripe_vars.publishable_key) {
      console.error("Card Oracle: Stripe publishable key not configured");
      return false;
    }

    try {
      stripe = Stripe(stripe_vars.publishable_key);
      elements = stripe.elements();
      cardElement = elements.create("card", { style: style });

      // Handle card Element validation errors.
      cardElement.on("change", function (event) {
        var displayError = document.getElementById("card-errors");
        if (displayError) {
          if (event.error) {
            displayError.textContent = event.error.message;
          } else {
            displayError.textContent = "";
          }
        }
      });

      return true;
    } catch (error) {
      console.error("Card Oracle: Failed to initialize Stripe:", error);
      return false;
    }
  }

  /**
   * Mount the card element when the form is present.
   */
  function mountCardElement() {
    var container = document.getElementById("card-element");
    if (!container) {
      return false;
    }

    if (cardMounted) {
      return true;
    }

    // Initialize Stripe if not already done.
    if (!cardElement) {
      if (!initializeStripe()) {
        return false;
      }
    }

    try {
      cardElement.mount("#card-element");
      cardMounted = true;
      return true;
    } catch (error) {
      console.error("Card Oracle: Failed to mount card element:", error);
      return false;
    }
  }

  /**
   * Show/hide loading state on the submit button.
   *
   * @param {boolean} isLoading - Whether to show loading state.
   */
  function setLoading(isLoading) {
    var submitButton = document.getElementById("stripe-submit");
    var buttonText = document.getElementById("stripe-button-text");
    var spinner = document.getElementById("stripe-spinner");

    if (submitButton) {
      submitButton.disabled = isLoading;
    }
    if (buttonText) {
      buttonText.style.display = isLoading ? "none" : "inline";
    }
    if (spinner) {
      spinner.style.display = isLoading ? "inline-block" : "none";
    }
  }

  /**
   * Display an error message to the user.
   *
   * @param {string} message - The error message to display.
   */
  function showError(message) {
    var errorElement = document.getElementById("card-errors");
    var paymentErrors = $(".payment-errors");

    if (errorElement) {
      errorElement.textContent = message;
    }
    if (paymentErrors.length) {
      paymentErrors.text(message);
    }
  }

  /**
   * Clear any displayed errors.
   */
  function clearErrors() {
    var errorElement = document.getElementById("card-errors");
    var paymentErrors = $(".payment-errors");

    if (errorElement) {
      errorElement.textContent = "";
    }
    if (paymentErrors.length) {
      paymentErrors.text("");
    }
  }

  /**
   * Create a PaymentIntent on the server.
   *
   * @param {Object} data - Payment data including amount, currency, email, etc.
   * @returns {Promise} - Resolves with the clientSecret.
   */
  function createPaymentIntent(data) {
    return new Promise(function (resolve, reject) {
      $.ajax({
        url: stripe_vars.ajax_url,
        type: "POST",
        data: {
          action: "card_oracle_create_payment_intent",
          nonce: stripe_vars.create_intent_nonce,
          amount: data.amount,
          currency: data.currency,
          order_id: data.order_id,
          description: data.description,
          receipt_email: data.receipt_email,
        },
        success: function (response) {
          if (response.success && response.data.clientSecret) {
            resolve(response.data);
          } else {
            var message =
              response.data && response.data.message
                ? response.data.message
                : "Failed to initialize payment. Please try again.";
            reject(new Error(message));
          }
        },
        error: function (xhr, status, error) {
          console.error(
            "Card Oracle: Create payment intent AJAX error:",
            status,
            error,
            xhr.responseText,
          );
          reject(
            new Error(
              "Network error. Please check your connection and try again.",
            ),
          );
        },
      });
    });
  }

  /**
   * Confirm the payment on the server after successful card confirmation.
   *
   * @param {Object} data - Data including payment_intent_id, order_id, redirect_url, subscribe, reading_id.
   * @returns {Promise} - Resolves with redirect URL.
   */
  function confirmPaymentOnServer(data) {
    return new Promise(function (resolve, reject) {
      $.ajax({
        url: stripe_vars.ajax_url,
        type: "POST",
        data: {
          action: "card_oracle_confirm_payment",
          nonce: stripe_vars.confirm_payment_nonce,
          payment_intent_id: data.payment_intent_id,
          order_id: data.order_id,
          redirect_url: data.redirect_url,
          subscribe: data.subscribe,
          reading_id: data.reading_id,
        },
        success: function (response) {
          if (response.success && response.data.redirect) {
            resolve(response.data);
          } else {
            var message =
              response.data && response.data.message
                ? response.data.message
                : "Payment verification failed. Please contact support.";
            reject(new Error(message));
          }
        },
        error: function (xhr, status, error) {
          console.error(
            "Card Oracle: Confirm payment AJAX error:",
            status,
            error,
            xhr.responseText,
          );
          var errorMsg = "Network error during payment confirmation.";
          if (xhr.responseText) {
            errorMsg +=
              " Server response: " + xhr.responseText.substring(0, 200);
          }
          reject(new Error(errorMsg));
        },
      });
    });
  }

  /**
   * Handle the form submission.
   *
   * @param {Event} event - The form submit event.
   */
  async function handleFormSubmit(event) {
    event.preventDefault();

    var form = document.getElementById("co-stripe-payment-form");
    if (!form || !cardElement) {
      showError(
        "Payment form not properly initialized. Please refresh the page.",
      );
      return;
    }

    // Get form data.
    var emailInput = document.getElementById("co-stripe-email");
    var amountInput = document.getElementById("co-stripe-amount");
    var currencyInput = document.getElementById("co-stripe-currency");
    var orderIdInput = document.getElementById("co-stripe-order-id");
    var descriptionInput = document.getElementById("co-stripe-description");
    var redirectInput = document.getElementById("co-stripe-redirect");
    var subscribeInput = document.getElementById("co-stripe-subscribe");
    var readingIdInput = document.getElementById("co-stripe-reading-id");

    var email = emailInput ? emailInput.value.trim() : "";
    var amount = amountInput ? amountInput.value : "";
    var currency = currencyInput ? currencyInput.value : "usd";
    var orderId = orderIdInput ? orderIdInput.value : "";
    var description = descriptionInput ? descriptionInput.value : "";
    var redirectUrl = redirectInput
      ? redirectInput.value
      : window.location.href;
    var subscribe = subscribeInput ? (subscribeInput.checked ? "1" : "0") : "0";
    var readingId = readingIdInput ? readingIdInput.value : "";

    // Debug logging for newsletter subscription fields.
    console.log(
      "Card Oracle Stripe: subscribe checkbox found:",
      !!subscribeInput,
      "checked:",
      subscribeInput ? subscribeInput.checked : "N/A",
      "value:",
      subscribe,
    );
    console.log(
      "Card Oracle Stripe: reading_id input found:",
      !!readingIdInput,
      "value:",
      readingId,
    );

    // Validate email.
    if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
      showError("Please enter a valid email address.");
      return;
    }

    // Clear any previous errors.
    clearErrors();

    // Show loading state.
    setLoading(true);

    try {
      // Step 1: Create PaymentIntent on the server.
      var intentData = await createPaymentIntent({
        amount: amount,
        currency: currency,
        order_id: orderId,
        description: description,
        receipt_email: email,
      });

      // Step 2: Confirm the card payment with Stripe (handles 3D Secure automatically).
      var result = await stripe.confirmCardPayment(intentData.clientSecret, {
        payment_method: {
          card: cardElement,
          billing_details: {
            email: email,
          },
        },
      });

      if (result.error) {
        // Show error to the customer (e.g., insufficient funds, card declined).
        showError(result.error.message);
        setLoading(false);
        return;
      }

      // Payment succeeded or requires further action (3D Secure handled by Stripe).
      if (result.paymentIntent && result.paymentIntent.status === "succeeded") {
        // Step 3: Confirm payment on our server and get redirect URL.
        var confirmData = await confirmPaymentOnServer({
          payment_intent_id: result.paymentIntent.id,
          order_id: orderId,
          redirect_url: redirectUrl,
          subscribe: subscribe,
          reading_id: readingId,
        });

        // Step 4: Redirect to success page.
        window.location.href = confirmData.redirect;
      } else {
        showError("Payment was not completed. Please try again.");
        setLoading(false);
      }
    } catch (error) {
      showError(
        error.message || "An unexpected error occurred. Please try again.",
      );
      setLoading(false);
    }
  }

  /**
   * Initialize the payment form.
   */
  function initPaymentForm() {
    // Only initialize if the payment form exists on this page.
    var form = document.getElementById("co-stripe-payment-form");
    if (!form) {
      return;
    }

    // Mount the card element.
    if (!mountCardElement()) {
      showError("Failed to initialize payment form. Please refresh the page.");
      return;
    }

    // Attach form submit handler.
    form.addEventListener("submit", handleFormSubmit);
  }

  /**
   * Initialize when DOM is ready.
   */
  $(document).ready(function () {
    initPaymentForm();
  });

  // Also try to initialize when window loads (for dynamically loaded content).
  $(window).on("load", function () {
    if (!cardMounted) {
      initPaymentForm();
    }
  });
})(jQuery);
