'use strict';
(function(window, document){
  if (typeof window === 'undefined') return;

  var U = window.KNSDD_Utils || {};

  // DOM ready helper
  U.ready = function(fn){
    try{
      if(document.readyState !== 'loading'){ fn(); }
      else { document.addEventListener('DOMContentLoaded', fn); }
    }catch(_){ try{ fn(); }catch(__){} }
  };

  // Debounce helper
  U.debounce = function(fn, wait){
    var t; return function(){ var ctx=this, args=arguments; clearTimeout(t); t=setTimeout(function(){ fn.apply(ctx,args); }, wait||0); };
  };

  // Select first matching element from comma-separated selectors
  U.qsAny = function(selectorList, root){
    root = root || document;
    try{
      var sel = (selectorList||'').split(',').map(function(s){ return s.trim(); }).filter(Boolean);
      for (var i=0;i<sel.length;i++){ var el = root.querySelector(sel[i]); if(el) return el; }
    }catch(_){ }
    return null;
  };

  // Select all elements from comma-separated selectors
  U.qsaAny = function(selectorList, root){
    root = root || document;
    var out = [];
    try{
      var sel = (selectorList||'').split(',').map(function(s){ return s.trim(); }).filter(Boolean);
      for (var i=0;i<sel.length;i++){
        try{ out = out.concat([].slice.call(root.querySelectorAll(sel[i]))); }catch(_){ }
      }
    }catch(_){ }
    return out;
  };

  // Normalize price node (accept wrapper or inner .price)
  U.getPriceNode = function(el){
    if(!el) return null;
    try{
      if(el.matches && el.matches('.price, .woocommerce-Price-amount, .amount')) return el;
      if(el.querySelector){ var inner = el.querySelector('.price, .woocommerce-Price-amount, .amount'); if(inner) return inner; }
    }catch(_){}
    return el;
  };

  // Exclude nodes inside disallowed areas (carousels, related, menus, etc.)
  U.isInDisallowed = function(el){
    try{
      var bad = el.closest('.wd-products-element, .wd-carousel-container, .related, .upsells, .cross-sells, .wd-dropdown-menu, .wd-sticky-nav, .wd-nav, nav, .menu, header, aside, [data-widget_type*="products"], [data-widget_type*="wd_products"]');
      var ok  = el.closest('.elementor-widget-woocommerce-product-price, [data-widget_type="woocommerce-product-price.default"]');
      return !!(bad && !ok);
    }catch(_){ return false; }
  };

  // Basic visibility check
  U.isVisible = function(el){
    try{
      var cs = getComputedStyle(el);
      if(cs.display === 'none' || cs.visibility === 'hidden') return false;
      if(el.offsetWidth === 0 && el.offsetHeight === 0) return false;
      return true;
    }catch(_){ return true; }
  };

  // Form product match helper
  U.formMatchesProduct = function(el, pid){
    try{
      var add = el.querySelector('[name="add-to-cart"]');
      var prod = el.querySelector('input[name="product_id"]');
      var v1 = add ? parseInt(add.value, 10) : 0;
      var v2 = prod ? parseInt(prod.value, 10) : 0;
      if(pid && (v1 === pid || v2 === pid)) return true;
    }catch(_){ }
    return false;
  };

  // Get product id from form/body classes
  U.getProductId = function(){
    try{
      var input = document.querySelector('form.cart input[name="product_id"]');
      if(input){ var v = parseInt(input.value, 10); if(!isNaN(v) && v>0) return v; }
      var addToCart = document.querySelector('form.cart [name="add-to-cart"]');
      if(addToCart){ var v2 = parseInt(addToCart.value, 10); if(!isNaN(v2) && v2>0) return v2; }
      var m = (document.body.className||'').match(/postid-(\d+)/);
      if(m && m[1]){ var v3 = parseInt(m[1], 10); if(!isNaN(v3) && v3>0) return v3; }
    } catch(_e){}
    return 0;
  };

  // Unique nodes preserving order
  U.uniqNodes = function(arr){
    var seen = new Set();
    var out = [];
    for(var i=0;i<arr.length;i++){
      var n = arr[i];
      if(!n || !n.nodeType) continue;
      if(seen.has(n)) continue;
      seen.add(n); out.push(n);
    }
    return out;
  };

  // Last node before a reference node in document order
  U.lastBefore = function(nodes, ref){
    if(!ref || !nodes || !nodes.length) return null;
    var pick = null;
    for(var i=0;i<nodes.length;i++){
      var n = nodes[i];
      try{
        if((n.compareDocumentPosition(ref) & Node.DOCUMENT_POSITION_FOLLOWING)){
          pick = n;
        }
      }catch(_){ }
    }
    return pick;
  };

  // Promise-based delay
  U.delay = function(ms){ return new Promise(function(res){ setTimeout(res, ms); }); };

  // Fetch with timeout and AbortController
  U.fetchWithTimeout = function(url, options, timeoutMs){
    var controller = (typeof AbortController !== 'undefined') ? new AbortController() : null;
    var id;
    if(controller){ options = options || {}; options.signal = controller.signal; }
    var p = fetch(url, options || {});
    if(!timeoutMs){ return p; }
    var timeout = new Promise(function(_, reject){
      id = setTimeout(function(){ if(controller) controller.abort(); reject(new Error('timeout')); }, timeoutMs);
    });
    return Promise.race([ p.finally(function(){ clearTimeout(id); }), timeout ]);
  };

  window.KNSDD_Utils = U;
})(window, document);
