/**
 *  Direct Order Popup Checkout scripts - FIXED VARIATION SYSTEM
 */
jQuery(function ($) {
  "use strict";

  // Cart model
  const cart = {
    items: [],
    subtotal: 0,
    shipping: 0,
    total: 0,
  };

  // Initialize
  function init() {
    bindEvents();
  }

  // Stripe Elements state
  var DOPW_stripe = null;
  var DOPW_stripe_elements = null;
  var DOPW_card_element = null;

  // Bind event handlers
  function bindEvents() {
    $(document).on("click", ".DOPW-quick-order-btn", openPopup);
    $(document).on("click", ".DOPW-close, .DOPW-cancel", closePopup);
    $(document).on("click", ".DOPW-popup", function (e) {
      if ($(e.target).is(".DOPW-popup")) closePopup();
    });
    $(document).on("click", ".DOPW-qty-btn.plus", increaseQuantity);
    $(document).on("click", ".DOPW-qty-btn.minus", decreaseQuantity);
    $(document).on("change", ".DOPW-quantity", updateQuantity);
    $(document).on("click", ".DOPW-remove-product", removeProduct);
    $(document).on("change", "#DOPW-shipping-method", updateShipping);
    $(document).on("submit", "#DOPW-order-form", handleSubmit);
    $(document).on("click", ".DOPW-place-order", function (e) {
      const $btn = $(this);
      if ($btn.prop("disabled")) return;
      $("#DOPW-order-form").trigger("submit");
    });

    // Payment method change: show Stripe element if Stripe selected
    $(document).on('change', 'input[name="DOPW_payment_method"]', function(){
      handlePaymentMethodChange($(this).val());
    });
  }

  function handlePaymentMethodChange(method_id){
    if (!method_id) return;
    var mid = String(method_id).toLowerCase();
    var isStripe = mid.indexOf('stripe') !== -1 || mid === 'woocommerce_payments' || mid.indexOf('woocommerce_payments') !== -1;
    // If DOPWData provides a stripe publishable key and selected method looks like stripe, initialize
    if (isStripe && typeof DOPWData !== 'undefined' && DOPWData.stripe_publishable_key) {
      showAndInitStripe();
    } else {
      destroyStripe();
    }

    // If the gateway exposes custom payment fields (e.g., PayPal Smart Buttons), fetch and render them
    try {
      if (typeof DOPWData !== 'undefined' && Array.isArray(DOPWData.gateways)) {
        var matched = DOPWData.gateways.find(function(g){ return String(g.id) === String(method_id); });
        if (matched && matched.has_fields) {
          // If this is also a Stripe-like gateway, the Stripe container will handle card UI
          if (matched.needs_card) {
            $('#DOPW-gateway-fields').empty();
          } else {
            // Fetch gateway fields from server
            var ajaxUrl = (typeof DOPWAjax !== 'undefined' && DOPWAjax.ajaxurl) ? DOPWAjax.ajaxurl : (typeof DOPWData !== 'undefined' && DOPWData.ajaxurl ? DOPWData.ajaxurl : '');
            var nonce = (typeof DOPWAjax !== 'undefined' && DOPWAjax.nonce) ? DOPWAjax.nonce : (typeof DOPWData !== 'undefined' && DOPWData.nonce ? DOPWData.nonce : '');
            if (ajaxUrl) {
              $.post(ajaxUrl, { action: 'DOPW_get_gateway_fields', nonce: nonce, gateway_id: method_id }, function(res){
                if (res && res.success && res.data) {
                  var d = res.data;
                  var scripts = Array.isArray(d.external_scripts) ? d.external_scripts : [];
                  var styles = Array.isArray(d.external_styles) ? d.external_styles : [];
                  var inline = Array.isArray(d.inline_scripts) ? d.inline_scripts : [];
                  var html = d.html || '';

                  // Helper: load styles
                  function loadStyles(list) {
                    return new Promise(function(resolve){
                      if (!list || !list.length) return resolve();
                      var loaded = 0;
                      list.forEach(function(href){
                        // avoid duplicate
                        if (document.querySelector('link[href="' + href + '"]')) { loaded++; if (loaded === list.length) resolve(); return; }
                        var l = document.createElement('link');
                        l.rel = 'stylesheet'; l.href = href;
                        l.onload = function(){ loaded++; if (loaded === list.length) resolve(); };
                        l.onerror = function(){ loaded++; if (loaded === list.length) resolve(); };
                        document.head.appendChild(l);
                      });
                    });
                  }

                  // Helper: load scripts sequentially
                  function loadScripts(list) {
                    return new Promise(function(resolve){
                      if (!list || !list.length) return resolve();
                      var i = 0;
                      function next(){
                        if (i >= list.length) return resolve();
                        var src = list[i++];
                        // avoid duplicate
                        if (document.querySelector('script[src="' + src + '"]')) { next(); return; }
                        var s = document.createElement('script');
                        s.src = src;
                        s.async = false;
                        s.onload = function(){ next(); };
                        s.onerror = function(){ next(); };
                        document.body.appendChild(s);
                      }
                      next();
                    });
                  }

                  loadStyles(styles).then(function(){
                    return loadScripts(scripts);
                  }).then(function(){
                    // Insert HTML markup (without scripts)
                    $('#DOPW-gateway-fields').html(html);
                    // Execute inline scripts
                    inline.forEach(function(code){
                      try {
                        var s = document.createElement('script');
                        s.type = 'text/javascript';
                        s.text = code;
                        document.body.appendChild(s);
                      } catch (e) { console.error('DOPW inline script error', e); }
                    });
                                    // Run any adapter logic for specific gateways (Paypal, WCPay, etc.)
                                    try { runGatewayAdapter(method_id); } catch (e) { console.error('Adapter error', e); }
                  }).catch(function(e){
                    console.error('Error loading gateway assets', e);
                    $('#DOPW-gateway-fields').html(html);
                  });
                } else {
                  $('#DOPW-gateway-fields').empty();
                }
              }, 'json').fail(function(){ $('#DOPW-gateway-fields').empty(); });
            }
          }
        } else {
          $('#DOPW-gateway-fields').empty();
        }
      }
    } catch (e) { console.error('DOPW gateway fields error', e); }
    // Also run adapter in case no gateway fields were required but adapter needs to initialize (e.g., WCPay)
    try { runGatewayAdapter(method_id); } catch (e) { console.error('Adapter init error', e); }
  }

  function showAndInitStripe(){
    $('#DOPW-stripe-container').show();
    if (DOPW_stripe && DOPW_card_element) return; // already initialized
    // Load Stripe.js dynamically if needed and allow passing a specific publishable key via DOPWData or adapter
    function initWithKey(publishableKey){
      try{
        var key = publishableKey || (typeof DOPWData !== 'undefined' ? DOPWData.stripe_publishable_key : null);
        if (!key) {
          console.error('DOPW: No Stripe publishable key available');
          return;
        }
        DOPW_stripe = Stripe(key);
        DOPW_stripe_elements = DOPW_stripe.elements();
        var style = {
          base: {
            color: '#32325d',
            fontFamily: 'Helvetica, Arial, sans-serif',
            fontSmoothing: 'antialiased',
            fontSize: '16px',
            '::placeholder': { color: '#aab7c4' }
          },
          invalid: { color: '#fa755a', iconColor: '#fa755a' }
        };
        DOPW_card_element = DOPW_stripe_elements.create('card', {style: style});
        DOPW_card_element.mount('#DOPW-stripe-element');
        DOPW_card_element.on('change', function(event){
          var displayError = document.getElementById('DOPW-stripe-errors');
          if (event.error) displayError.textContent = event.error.message;
          else displayError.textContent = '';
        });
      } catch (e) {
        console.error('DOPW Stripe init error', e);
      }
    }

    if (typeof Stripe === 'undefined') {
      var s = document.createElement('script');
      s.src = 'https://js.stripe.com/v3/';
      s.onload = function(){ initWithKey(); };
      document.head.appendChild(s);
    } else {
      initWithKey();
    }
  }

  // Run adapter hooks for specific gateways after gateway fields are injected
  function runGatewayAdapter(method_id){
    if (!method_id || typeof DOPWData === 'undefined' || !Array.isArray(DOPWData.gateways)) return;
    var g = DOPWData.gateways.find(function(x){ return String(x.id) === String(method_id); });
    if (!g) return;

    // If gateway needs card and provides a publishable key, prefer that for Stripe init
    try {
      if (g.needs_card) {
        var key = null;
        if (g.public_keys) {
          key = g.public_keys.stripe_publishable_key || g.public_keys.publishable_key || g.public_keys.test_publishable_key || null;
        }
        if (key) {
          // set global for later confirmations
          if (typeof DOPWData !== 'undefined') DOPWData.stripe_publishable_key = key;
          showAndInitStripe(key);
        } else {
          showAndInitStripe();
        }
      }
    } catch (e) { console.error('DOPW runGatewayAdapter stripe part', e); }

    // PayPal (Smart Buttons) adapter: ensure PayPal SDK is loaded if client id available
    try {
      var lid = String(g.id || '').toLowerCase();
      if (lid.indexOf('paypal') !== -1) {
        var clientId = null;
        if (g.public_keys) {
          clientId = g.public_keys.paypal_client_id || g.public_keys.client_id || g.public_keys.paypal_client_id_sandbox || null;
        }
        // fallback to DOPWData.public keys if present
        if (!clientId && typeof DOPWData !== 'undefined' && Array.isArray(DOPWData.gateways)) {
          // try find any paypal client id globally
          DOPWData.gateways.forEach(function(gg){ if (!clientId && gg.public_keys) clientId = gg.public_keys.paypal_client_id || gg.public_keys.client_id || null; });
        }
        if (clientId) {
          // load PayPal SDK if not already loaded
          if (!document.querySelector('script[src*="paypal.com/sdk/js"]')) {
            var paySrc = 'https://www.paypal.com/sdk/js?client-id=' + encodeURIComponent(clientId) + '&currency=' + (typeof DOPWData !== 'undefined' && DOPWData.currency ? DOPWData.currency : 'USD');
            var s = document.createElement('script'); s.src = paySrc; s.async = true;
            s.onload = function(){ console.log('PayPal SDK loaded'); };
            document.head.appendChild(s);
          }
        }
      }
    } catch (e) { console.error('DOPW runGatewayAdapter paypal part', e); }
    
    // Stripe Payment Request (Apple Pay / Google Pay) adapter
    try {
      var lid = String(g.id || '').toLowerCase();
      if ((lid.indexOf('stripe') !== -1 || lid === 'woocommerce_payments' || g.supports && g.supports.indexOf && g.supports.indexOf('payment_request') !== -1)) {
        // wait for Stripe to be ready
        var waitCount = 0;
        var prInterval = setInterval(function(){
          waitCount++;
          if (typeof DOPW_stripe !== 'undefined' && DOPW_stripe && DOPW_stripe.paymentRequest) {
            clearInterval(prInterval);
            try {
              var totalAmount = Math.round((cart.total || 0) * 100);
              if (totalAmount <= 0) return;
              var currency = (typeof DOPWData !== 'undefined' && DOPWData.currency) ? DOPWData.currency : (typeof DOPWData !== 'undefined' && DOPWData.currency_symbol ? 'USD' : 'USD');
              var paymentRequest = DOPW_stripe.paymentRequest({
                country: (typeof DOPWData !== 'undefined' && DOPWData.country) ? DOPWData.country : 'US',
                currency: currency,
                total: { label: 'Total', amount: totalAmount },
                requestPayerName: true,
                requestPayerEmail: true
              });

              paymentRequest.canMakePayment().then(function(result){
                if (result) {
                  $('#DOPW-payment-request-button').show();
                  var prElement = DOPW_stripe.elements().create('paymentRequestButton', { paymentRequest: paymentRequest });
                  try { prElement.mount('#DOPW-payment-request-button'); } catch (e) { console.warn('Could not mount paymentRequestButton', e); }

                  paymentRequest.on('paymentmethod', function(ev){
                    // Create the order server-side with payment method id
                    var name = $('#DOPW-name').val().trim();
                    var phone = $('#DOPW-phone').val().trim();
                    var address = $('#DOPW-address').val().trim();
                    var email = $('#DOPW-email').val().trim();
                    var itemsPayload = cart.items.map(function(it){ return { id: it.id_raw, quantity: it.quantity, price: it.price, product_type: it.type, variation_id: it.variation_id || 0, variation_attributes: it.variation_attributes || {} }; });
                    var nonce = (typeof DOPWAjax !== 'undefined' && DOPWAjax.nonce) ? DOPWAjax.nonce : (typeof DOPWData !== 'undefined' && DOPWData.nonce ? DOPWData.nonce : '');
                    var ajaxUrl = (typeof DOPWAjax !== 'undefined' && DOPWAjax.ajaxurl) ? DOPWAjax.ajaxurl : (typeof DOPWData !== 'undefined' && DOPWData.ajaxurl ? DOPWData.ajaxurl : '');
                    // send payment_method id returned by paymentRequest
                    var pmid = (ev && ev.paymentMethod && (ev.paymentMethod.id || ev.paymentMethod.payment_method || ev.paymentMethod.token)) ? (ev.paymentMethod.id || ev.paymentMethod.payment_method || ev.paymentMethod.token) : null;
                    if (!ajaxUrl) { ev.complete('fail'); alert('Configuration error.'); return; }
                    $.post(ajaxUrl, {
                      action: 'DOPW_process_order',
                      nonce: nonce,
                      payment_method_id: pmid,
                      save_payment_method: 0,
                      customer: { name: name, phone: phone, email: email, address: address },
                      order: { items: itemsPayload, shipping_method: $('#DOPW-shipping-method').val(), payment_method: method_id, subtotal: cart.subtotal, shipping: cart.shipping, total: cart.total }
                    }, function(resp){
                      if (resp && resp.success) {
                        // Let Stripe know
                        ev.complete('success');
                        // If redirect present
                        if (resp.data && resp.data.redirect) { window.location = resp.data.redirect; return; }
                        if (resp.data && resp.data.gateway_result && resp.data.gateway_result.client_secret) {
                          // confirm client side
                          window.DOPWHandleGatewayResult && window.DOPWHandleGatewayResult(resp.data.gateway_result, resp.data);
                          return;
                        }
                        if (resp.data && resp.data.order_id) { window.location = resp.data.redirect || window.location.href; return; }
                        alert('Payment succeeded');
                        resetForm(); closePopup();
                      } else {
                        ev.complete('fail');
                        var msg = resp && resp.data && resp.data.message ? resp.data.message : 'Payment failed';
                        alert('Payment failed: ' + msg);
                      }
                    }, 'json').fail(function(){ ev.complete('fail'); alert('Payment error'); });
                  });
                }
              });
            } catch (err) { console.error('Payment Request init error', err); }
          }
          if (waitCount > 10) clearInterval(prInterval);
        }, 300);
      }
    } catch (e) { console.error('DOPW runGatewayAdapter payment request part', e); }
  }

  function destroyStripe(){
    $('#DOPW-stripe-container').hide();
    $('#DOPW-stripe-errors').text('');
    if (DOPW_card_element) {
      try { DOPW_card_element.unmount(); } catch(e){}
    }
    DOPW_card_element = null;
    DOPW_stripe_elements = null;
    DOPW_stripe = null;
    $('#DOPW-stripe-element').empty();
  }

  // Default gateway result handler: support Stripe PaymentIntent confirmation
  window.DOPWHandleGatewayResult = function(gateway_result, response_data) {
    if (!gateway_result) return;
    var clientSecret = gateway_result.client_secret || gateway_result.payment_intent_client_secret || (gateway_result.payment_intent && gateway_result.payment_intent.client_secret) || null;
    if (!clientSecret) return;
    if (typeof DOPWData === 'undefined' || !DOPWData.stripe_publishable_key) {
      console.warn('Stripe publishable key not available for client-side confirmation.');
      return;
    }

    // Ensure Stripe is initialized and card element exists
    if (!DOPW_stripe || !DOPW_card_element) {
      showAndInitStripe();
      setTimeout(function(){
        if (!DOPW_stripe || !DOPW_card_element) {
          console.error('Stripe not initialized');
          return;
        }
        confirmStripePayment(clientSecret, response_data);
      }, 800);
      return;
    }

    confirmStripePayment(clientSecret, response_data);
  };

  function confirmStripePayment(clientSecret, response_data) {
    var name = $('#DOPW-name').val() || '';
    var email = $('#DOPW-email').val() || '';
    var displayError = document.getElementById('DOPW-stripe-errors');
    DOPW_stripe.confirmCardPayment(clientSecret, {
      payment_method: {
        card: DOPW_card_element,
        billing_details: {
          name: name,
          email: email
        }
      }
    }).then(function(result){
      if (result.error) {
        if (displayError) displayError.textContent = result.error.message;
        alert('Payment failed: ' + (result.error.message || 'Unknown'));
      } else if (result.paymentIntent && result.paymentIntent.status === 'succeeded') {
        // Payment succeeded
        if (response_data && response_data.redirect) {
          window.location = response_data.redirect;
          return;
        }
        // Otherwise reload or show order received
        if (response_data && response_data.order_id) {
          var url = response_data.redirect || window.location.href;
          if (response_data.redirect) window.location = response_data.redirect; else window.location.reload();
          return;
        }
        alert('Payment completed successfully.');
        if (displayError) displayError.textContent = '';
      }
    });
  }

  // Open popup
  function openPopup(e) {
    e && e.preventDefault();
    const $btn = $(this);
    const productId = $btn.data("product-id");
    const productType = $btn.data("product-type") || "simple";

    if (!productId) return;

    const product = {
      id: String(productId),
      id_raw: productId,
      type: productType,
      title: $btn.data("product-title") || "",
      price: parseFloat($btn.data("product-price") || 0) || 0,
      priceFormatted: $btn.data("product-price-formatted") || null,
      image: $btn.data("product-image-url") || "",
      quantity: 1,
      variation_id: 0,
      variation_valid: false,
      original_title: $btn.data("product-title") || "",
      original_price: parseFloat($btn.data("product-price") || 0) || 0,
    };

    $("#DOPW-popup").fadeIn(200);
    $("body").addClass("DOPW-open");

    if (product.type === "variable") {
      fetchVariationsAndRender(product.id_raw, function () {
        const existing = cart.items.find(
          (it) => String(it.id) === String(product.id)
        );
        if (existing) {
          existing.quantity += 1;
        } else {
          cart.items.push(product);
        }
        updateProductList();
        updateTotals();
        updatePlaceOrderButton();
        // initialize payment UI (e.g., Stripe) based on selected method
        handlePaymentMethodChange($('input[name="DOPW_payment_method"]:checked').val());
      });
    } else {
      const existing = cart.items.find(
        (it) => String(it.id) === String(product.id)
      );
      if (existing) {
        existing.quantity += 1;
      } else {
        cart.items.push(product);
      }
      updateProductList();
      updateTotals();
      updatePlaceOrderButton();
      // initialize payment UI (e.g., Stripe) based on selected method
      handlePaymentMethodChange($('input[name="DOPW_payment_method"]:checked').val());
    }
  }

  // Update product list
  function updateProductList() {
    const $list = $("#DOPW-product-list");
    $list.empty();

    cart.items.forEach((item, index) => {
      const rowTotal =
        (parseFloat(item.price) || 0) * (parseInt(item.quantity) || 0);
      let variationInfo = "";
      let statusClass = "";
      let displayTitle = item.title;

      if (item.type === "variable") {
        if (
          item.variation_attributes &&
          Object.values(item.variation_attributes).some((val) => val !== "")
        ) {
          const attrDisplay = [];
          Object.keys(item.variation_attributes).forEach((attrKey) => {
            const attrValue = item.variation_attributes[attrKey];
            if (attrValue && attrValue !== "") {
              const attrName = attrKey
                .replace(/(^attribute_pa_|^attribute_)/i, "")
                .replace(/_/g, " ");
              attrDisplay.push(`${attrName}: ${attrValue}`);
            }
          });

          variationInfo =
            '<div class="DOPW-variation-info">' +
            attrDisplay.join(", ") +
            "</div>";
          statusClass = item.variation_valid
            ? "DOPW-variation-valid"
            : "DOPW-variation-invalid";
        } else {
          variationInfo =
            '<div class="DOPW-variation-info DOPW-variation-required">Please select variation</div>';
          statusClass = "DOPW-variation-required";
          displayTitle = item.original_title;
        }
      }

      const $row = $(
        '<div class="DOPW-product-row ' +
          statusClass +
          '" data-product-id="' +
          item.id +
          '" data-product-raw-id="' +
          item.id_raw +
          '" data-item-index="' +
          index +
          '">' +
          '  <div class="DOPW-product-image"><img src="' +
          (item.image || "") +
          '" alt="' +
          escapeHtml(displayTitle) +
          '"></div>' +
          '  <div class="DOPW-product-info">' +
          "    <h5 class='DOPW-product-title'>" +
          escapeHtml(displayTitle) +
          "</h5>" +
          variationInfo +
          '    <div class="DOPW-product-price">' +
          formatPrice(item.price) +
          "</div>" +
          "  </div>" +
          '  <div class="DOPW-quantity-wrapper">' +
          '    <button type="button" class="DOPW-qty-btn minus">-</button>' +
          '    <input type="number" class="DOPW-quantity" value="' +
          (item.quantity || 1) +
          '" min="1" max="999">' +
          '    <button type="button" class="DOPW-qty-btn plus">+</button>' +
          "  </div>" +
          '  <div class="DOPW-row-total">' +
          formatPrice(rowTotal) +
          "</div>" +
          '  <button type="button" class="DOPW-remove-product">&times;</button>' +
          "</div>"
      );

      $list.append($row);
    });
  }

  // Quantity functions
  function increaseQuantity() {
    const $row = $(this).closest(".DOPW-product-row");
    const $input = $row.find(".DOPW-quantity");
    $input.val(Math.max(1, parseInt($input.val() || 0) + 1)).trigger("change");
  }

  function decreaseQuantity() {
    const $row = $(this).closest(".DOPW-product-row");
    const $input = $row.find(".DOPW-quantity");
    const v = parseInt($input.val() || 0);
    if (v > 1) $input.val(v - 1).trigger("change");
  }

  function updateQuantity() {
    const $row = $(this).closest(".DOPW-product-row");
    const id = String($row.data("product-id"));
    const rawId = $row.data("product-raw-id");
    const itemIndex = $row.data("item-index");

    let val = parseInt($(this).val(), 10);
    if (isNaN(val) || val < 1) val = 1;
    $(this).val(val);

    const item =
      cart.items[itemIndex] ||
      cart.items.find(
        (it) => String(it.id) === id || String(it.id_raw) === String(rawId)
      );
    if (item) {
      item.quantity = val;
      updateProductList();
      updateTotals();
    }
  }

  function removeProduct() {
    const $row = $(this).closest(".DOPW-product-row");
    const id = String($row.data("product-id"));
    const rawId = $row.data("product-raw-id");

    cart.items = cart.items.filter(
      (it) => String(it.id) !== id && String(it.id_raw) !== String(rawId)
    );
    $row.fadeOut(200, function () {
      $(this).remove();
      updateTotals();
      updatePlaceOrderButton();

      const hasVariableProducts = cart.items.some(
        (it) => it.type === "variable"
      );
      if (!hasVariableProducts) {
        $("#DOPW-variation-selectors").empty();
      }
    });
  }

  function updateShipping() {
    const cost = parseFloat($(this).find(":selected").data("cost") || 0) || 0;
    cart.shipping = cost;
    $(".DOPW-shipping-amount").text(formatPrice(cost));
    updateTotals();
  }

  function updateTotals() {
    cart.subtotal = 0;
    cart.items.forEach((item) => {
      cart.subtotal +=
        (parseFloat(item.price) || 0) * (parseInt(item.quantity) || 0);
    });
    const $sel = $("#DOPW-shipping-method");
    if ($sel.length) {
      cart.shipping =
        parseFloat($sel.find(":selected").data("cost") || cart.shipping || 0) ||
        0;
    }
    cart.total = cart.subtotal + (cart.shipping || 0);
    $(".DOPW-subtotal-amount").text(formatPrice(cart.subtotal));
    $(".DOPW-shipping-amount").text(formatPrice(cart.shipping));
    $(".DOPW-total-amount").text(formatPrice(cart.total));
  }

  // Fetch variations
  function fetchVariationsAndRender(productId, callback) {
    // FIXED: Get ajaxurl from localized script data
    const ajaxUrl =
      typeof DOPWAjax !== "undefined" && DOPWAjax.ajaxurl
        ? DOPWAjax.ajaxurl
        : typeof DOPWData !== "undefined" && DOPWData.ajaxurl
        ? DOPWData.ajaxurl
        : "";

    if (!ajaxUrl) {
      console.error(
        "DOPW Error: Ajax URL not found. Please ensure wp_localize_script is configured correctly."
      );
      if (callback) callback();
      return;
    }

    const nonce =
      typeof DOPWAjax !== "undefined" && DOPWAjax.nonce ? DOPWAjax.nonce : "";

    $.post(
      ajaxUrl,
      {
        action: "DOPW_get_variations",
        product_id: productId,
        nonce: nonce,
      },
      function (res) {
        if (res && res.success && res.data) {
          renderVariationForm(
            productId,
            res.data.attributes,
            res.data.variations
          );
        }
        if (callback) callback();
      }
    );
  }

  // Render variation form with improved matching
  function renderVariationForm(productId, attributes, variations) {
    const $wrap = $("#DOPW-variation-selectors");
    $wrap.empty();

    if (!attributes || Object.keys(attributes).length === 0) return;

    window.DOPWVariationsData = {
      productId: productId,
      attributes: attributes,
      variations: variations,
    };

    let html =
      '<div class="DOPW-variations-wrapper" data-product-id="' +
      productId +
      '">';
    html += '<table class="variations" cellspacing="0"><tbody>';

    Object.keys(attributes).forEach((attrKey) => {
      const opts = attributes[attrKey] || [];
      const cleaned = attrKey
        .replace(/(^attribute_pa_|^attribute_|^pa_)/i, "")
        .replace(/_/g, " ");
      const fieldId = `DOPW_attribute_${attrKey.replace(/[^a-z0-9_-]/gi, "_")}`;

      html += '<tr class="DOPW-variation-row">';
      html +=
        '<td class="label"><label for="' +
        fieldId +
        '">' +
        escapeHtml(cleaned) +
        "</label></td>";
      html += '<td class="value">';
      html +=
        '<select id="' +
        fieldId +
        '" name="' +
        attrKey +
        '" data-attribute-name="' +
        attrKey +
        '" class="DOPW-attribute-select">';
      html += '<option value="">Choose an option</option>';

      opts.forEach((opt) => {
        const value = opt && opt.slug ? String(opt.slug) : String(opt);
        const text = opt && opt.label ? opt.label : String(opt);
        html +=
          '<option value="' +
          escapeHtml(value) +
          '">' +
          escapeHtml(text) +
          "</option>";
      });

      html += "</select>";
      html += "</td>";
      html += "</tr>";
    });

    html += "</tbody></table>";
    html += "</div>";

    $wrap.append(html);

    $wrap.find(".DOPW-attribute-select").on("change", function () {
      handleVariationChange(productId, attributes, variations);
    });

    handleVariationChange(productId, attributes, variations);
  }

  // Handle variation selection changes
  function handleVariationChange(productId, attributes, variations) {
    const $selects = $(".DOPW-attribute-select");
    const selected = {};
    let allSelected = true;

    $selects.each(function () {
      const $select = $(this);
      const attrName = $select.data("attribute-name");
      const value = $select.val();

      if (!value || value === "") {
        allSelected = false;
      } else {
        selected["attribute_" + attrName] = String(value).toLowerCase().trim();
      }
    });

    if (!allSelected) {
      applyMatchedVariation(null, productId);
      return;
    }

    let matched = null;
    for (const variation of variations) {
      if (!variation.attributes) continue;

      let isMatch = true;

      for (const selectedKey in selected) {
        const selectedValue = selected[selectedKey];
        const variationValue = String(variation.attributes[selectedKey] || "")
          .toLowerCase()
          .trim();

        if (variationValue === "" || variationValue === selectedValue) continue;
        isMatch = false;
        break;
      }

      if (isMatch) {
        for (const varKey in variation.attributes) {
          const varValue = String(variation.attributes[varKey] || "").trim();
          if (varValue !== "" && !selected[varKey]) {
            isMatch = false;
            break;
          }
        }
      }

      if (isMatch) {
        matched = variation;
        break;
      }
    }

    applyMatchedVariation(matched, productId);
  }

  // Apply matched variation data to cart item
  function applyMatchedVariation(matched, productId) {
    const cartItem = cart.items.find(
      (it) =>
        String(it.id_raw) === String(productId) ||
        String(it.id) === String(productId)
    );
    if (!cartItem) return;

    if (!matched) {
      cartItem.variation_valid = false;
      cartItem.variation_id = 0;
      cartItem.variation_attributes = {};
      cartItem.price = cartItem.original_price || 0;
      cartItem.title = cartItem.original_title || cartItem.title;
    } else {
      cartItem.variation_id = matched.variation_id || 0;
      cartItem.variation_attributes = matched.attributes || {};
      cartItem.price = parseFloat(
        matched.display_price || matched.price || cartItem.original_price || 0
      );

      const attrDisplay = [];
      if (matched.attributes) {
        Object.keys(matched.attributes).forEach(function (k) {
          const v = matched.attributes[k];
          if (v && v !== "") {
            const name = k
              .replace(/(^attribute_pa_|^attribute_|^pa_)/i, "")
              .replace(/_/g, " ");
            attrDisplay.push(name + ": " + v);
          }
        });
      }

      cartItem.title =
        cartItem.original_title +
        (attrDisplay.length ? " - " + attrDisplay.join(", ") : "");
      cartItem.variation_valid =
        matched.is_in_stock !== false && matched.is_purchasable !== false;

      if (matched.image && matched.image.src) {
        cartItem.image = matched.image.src;
      }
    }

    updateProductList();
    updateTotals();
    updatePlaceOrderButton();
  }

  function updatePlaceOrderButton() {
    const hasItems = cart.items.length > 0;
    const allVariationsValid = cart.items.every(
      (it) => it.type !== "variable" || (it.variation_valid && it.variation_id)
    );
    $(".DOPW-place-order").prop("disabled", !hasItems || !allVariationsValid);
  }

  // Submit order
  function handleSubmit(e) {
    e.preventDefault();

    const shippingMethod = $("#DOPW-shipping-method").val();
    const paymentMethod = $('input[name="DOPW_payment_method"]:checked').val();
    const name = $("#DOPW-name").val().trim();
    const phone = $("#DOPW-phone").val().trim();
    const address = $("#DOPW-address").val().trim();
    const email = $("#DOPW-email").val().trim();

    const missingFields = [];
    if (!name) missingFields.push("Name");
    if (!phone) missingFields.push("Phone");
    if (!address) missingFields.push("Address");
    if (!shippingMethod) missingFields.push("Shipping Method");
    if (!paymentMethod) missingFields.push("Payment Method");
    if (missingFields.length > 0) {
      alert(`Please complete: ${missingFields.join(", ")}`);
      return;
    }
    if (cart.items.length === 0) {
      alert("Please add at least one product");
      return;
    }

    const invalidVariations = cart.items.filter(
      (it) =>
        it.type === "variable" && (!it.variation_valid || !it.variation_id)
    );
    if (invalidVariations.length > 0) {
      alert(
        `Please select variations for: ${invalidVariations
          .map((it) => it.original_title)
          .join(", ")}`
      );
      return;
    }

    const itemsPayload = cart.items.map((it) => ({
      id: it.id_raw,
      quantity: it.quantity,
      price: it.price,
      product_type: it.type,
      ...(it.type === "variable" &&
        it.variation_id && {
          variation_id: it.variation_id,
          variation_attributes: it.variation_attributes || {},
        }),
    }));

    const nonce =
      $("#DOPW-nonce").val() ||
      (typeof DOPWAjax !== "undefined" && DOPWAjax.nonce ? DOPWAjax.nonce : "");

    // FIXED: Get ajaxurl from localized script data
    const ajaxUrl =
      typeof DOPWAjax !== "undefined" && DOPWAjax.ajaxurl
        ? DOPWAjax.ajaxurl
        : typeof DOPWData !== "undefined" && DOPWData.ajaxurl
        ? DOPWData.ajaxurl
        : "";

    if (!ajaxUrl) {
      console.error(
        "DOPW Error: Ajax URL not found. Please ensure wp_localize_script is configured correctly."
      );
      alert("Configuration error. Please contact support.");
      return;
    }

    const $submitBtn = $(".DOPW-place-order");
    const originalText = $submitBtn.text();
    $submitBtn.prop("disabled", true).text("Placing Order...");

    // If Stripe is selected and we have a card element, create a PaymentMethod first
    const pmid = String(paymentMethod || '').toLowerCase();
    const isStripe = pmid.indexOf('stripe') !== -1 || pmid === 'woocommerce_payments' || pmid.indexOf('woocommerce_payments') !== -1;
    if (isStripe && typeof DOPW_stripe !== 'undefined' && DOPW_stripe && DOPW_card_element) {
      DOPW_stripe.createPaymentMethod({
        type: 'card',
        card: DOPW_card_element,
        billing_details: { name: name, email: email }
      }).then(function(pmResult){
        if (pmResult.error) {
          alert('Card error: ' + (pmResult.error.message || '')); 
          $submitBtn.prop('disabled', false).text(originalText);
          return;
        }
        const payment_method_id = pmResult.paymentMethod ? pmResult.paymentMethod.id : (pmResult.id || null);
        // Include save payment checkbox value if present
        const savePayment = $('#DOPW-save-payment-method').length ? ($('#DOPW-save-payment-method').prop('checked') ? 1 : 0) : 0;

        $.ajax({
          url: ajaxUrl,
          type: 'POST',
          data: {
            action: 'DOPW_process_order',
            nonce,
            payment_method_id: payment_method_id,
            save_payment_method: savePayment,
            customer: { name, phone, email, address },
            order: {
              items: itemsPayload,
              shipping_method: shippingMethod,
              payment_method: paymentMethod,
              subtotal: cart.subtotal,
              shipping: cart.shipping,
              total: cart.total,
            },
          },
          dataType: 'json',
          timeout: 30000
        }).done(handleAjaxDone).fail(handleAjaxFail).always(function(){ $submitBtn.prop('disabled', false).text(originalText); });
      });
      return;
    }

    $.ajax({
      url: ajaxUrl,
      type: "POST",
      data: {
        action: "DOPW_process_order",
        nonce,
        customer: { name, phone, email, address },
        order: {
          items: itemsPayload,
          shipping_method: shippingMethod,
          payment_method: paymentMethod,
          subtotal: cart.subtotal,
          shipping: cart.shipping,
          total: cart.total,
        },
      },
      dataType: "json",
      timeout: 30000,
    })
      .done((response) => {
        if (response && response.success) {
          // If gateway returned a redirect URL (Stripe Checkout, PayPal Standard etc.)
          if (response.data && response.data.redirect) {
            // Allow gateway redirect to happen in top-level window
            window.location = response.data.redirect;
            return;
          }

          // If gateway returned structured gateway response, handle common flows
          if (response.data && response.data.gateway_result) {
            const g = response.data.gateway_result;
            // Redirect if gateway asks for it
            if (g && g.result === 'success' && g.redirect) {
              window.location = g.redirect;
              return;
            }

            // If gateway_result contains a Stripe client_secret, attempt to confirm
            if (g && (g.client_secret || g.payment_intent_client_secret || g.payment_intent)) {
              // Normalize possible keys
              const clientSecret = g.client_secret || g.payment_intent_client_secret || (g.payment_intent && g.payment_intent.client_secret) || null;
              if (clientSecret) {
                // Ensure Stripe is initialized
                if (typeof DOPWData !== 'undefined' && DOPWData.stripe_publishable_key) {
                  if (!DOPW_stripe || !DOPW_card_element) {
                    showAndInitStripe();
                    // small delay to allow Stripe to initialize
                    setTimeout(function(){
                      if (window.DOPWHandleGatewayResult) {
                        window.DOPWHandleGatewayResult(g, response.data);
                        return;
                      }
                    }, 800);
                  } else {
                    if (window.DOPWHandleGatewayResult) {
                      window.DOPWHandleGatewayResult(g, response.data);
                      return;
                    }
                  }
                } else {
                  // No publishable key available; forward to custom handler if present
                  if (typeof window.DOPWHandleGatewayResult === 'function') {
                    try { window.DOPWHandleGatewayResult(g, response.data); return; } catch (err) { console.error(err); }
                  }
                }
                return;
              }
            }

            // Fallback: forward gateway_result to custom handler if present
            if (typeof window.DOPWHandleGatewayResult === 'function') {
              try { window.DOPWHandleGatewayResult(g, response.data); return; } catch (err) { console.error('DOPW gateway handler error', err); }
            }
          }

          // Default success path: go to order received page if provided
          if (response.data && response.data.order_id) {
            const redirect = response.data.redirect || (typeof window.location !== 'undefined' ? window.location.href : null);
            if (response.data.redirect) {
              window.location = response.data.redirect;
              return;
            }
            // Show success message and close popup if no redirect
            alert(`Order placed successfully! ID: ${response.data.order_id}`);
            resetForm();
            closePopup();
            return;
          }

          // Fallback success
          alert('Order placed successfully.');
          resetForm();
          closePopup();
        } else {
          const errorMessage = response && response.data && response.data.message ? response.data.message : 'Failed to place order';
          alert(`Order failed: ${errorMessage}`);
        }
      })
      .fail(function(jqXHR, textStatus, errorThrown) {
        var msg = 'An error occurred while placing the order.';
        try {
          if (jqXHR && jqXHR.responseText) {
            try {
              var json = JSON.parse(jqXHR.responseText);
              if (json && json.data && json.data.message) {
                msg = 'Order failed: ' + json.data.message;
              } else if (json && json.message) {
                msg = 'Order failed: ' + json.message;
              } else {
                console.error('DOPW AJAX error response (parsed):', json);
              }
            } catch (e) {
              console.error('DOPW AJAX error responseText (not JSON):', jqXHR.responseText);
            }
          }
        } catch (e) {
          /* ignore */
        }
        console.error('DOPW AJAX fail', textStatus, errorThrown, jqXHR);
        alert(msg + (errorThrown ? (' (' + errorThrown + ')') : ''));
      })
      .always(function() {
        $submitBtn.prop("disabled", false).text(originalText);
      });

      // helper handlers for stripe-created-path
      function handleAjaxDone(response){
        // reuse same success logic
        if (response && response.success) {
          if (response.data && response.data.redirect) {
            window.location = response.data.redirect;
            return;
          }
          if (response.data && response.data.gateway_result) {
            var g = response.data.gateway_result;
            if (g && (g.client_secret || g.payment_intent_client_secret || (g.payment_intent && g.payment_intent.client_secret))) {
              window.DOPWHandleGatewayResult && window.DOPWHandleGatewayResult(g, response.data);
              return;
            }
          }
          if (response.data && response.data.order_id) {
            alert('Order placed successfully! ID: ' + response.data.order_id);
            resetForm(); closePopup();
            return;
          }
          alert('Order placed successfully.'); resetForm(); closePopup();
        } else {
          var msg = (response && response.data && response.data.message) ? response.data.message : 'Failed to place order';
          alert('Order failed: ' + msg);
        }
      }

      function handleAjaxFail(jqXHR, textStatus, errorThrown){
        var msg = 'An error occurred while placing the order.';
        try {
          if (jqXHR && jqXHR.responseText) {
            try {
              var json = JSON.parse(jqXHR.responseText);
              if (json && json.data && json.data.message) {
                msg = 'Order failed: ' + json.data.message;
              } else if (json && json.message) {
                msg = 'Order failed: ' + json.message;
              } else {
                console.error('DOPW AJAX error response (parsed):', json);
              }
            } catch (e) {
              console.error('DOPW AJAX error responseText (not JSON):', jqXHR.responseText);
            }
          }
        } catch (e) {
          /* ignore */
        }
        console.error('DOPW AJAX fail', textStatus, errorThrown, jqXHR);
        alert(msg + (errorThrown ? (' (' + errorThrown + ')') : ''));
      }
  }

  // Helpers
  function escapeHtml(str) {
    if (!str && str !== 0) return "";
    return String(str)
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;");
  }

  function formatPrice(price) {
    price = parseFloat(price) || 0;
    const data =
      typeof DOPWData !== "undefined"
        ? DOPWData
        : typeof woocommerce_params !== "undefined"
        ? woocommerce_params
        : null;
    if (typeof accounting !== "undefined") {
      if (data)
        return accounting.formatMoney(price, {
          symbol: data.currency_symbol || "$",
          decimal: data.decimal_separator || ".",
          thousand: data.thousand_separator || ",",
          precision: parseInt(data.decimals) || 2,
          format: data.price_format || "%s%v",
        });
      return accounting.formatMoney(price, { symbol: "$", precision: 2 });
    }
    return price.toFixed(2);
  }

  function resetForm() {
    $("#DOPW-order-form")[0].reset();
    cart.items = [];
    cart.subtotal = 0;
    cart.shipping = 0;
    cart.total = 0;
    $("#DOPW-variation-selectors").empty();
    updateProductList();
    updateTotals();
    updatePlaceOrderButton();
  }

  function closePopup() {
    $("#DOPW-popup").fadeOut(200);
    $("body").removeClass("DOPW-open");
  }

  init();
});
