/**
 * Theme Overrides - Dynamic JavaScript styling for form elements
 *
 * This file contains JavaScript that applies theme styles to elements that cannot
 * be styled purely with CSS (pseudo-elements, input-groups, etc.)
 */

/**
 * Apply accent color to checkbox and radio inputs
 * Extracts accent-color from theme CSS and applies it directly to the element
 */
jQuery(document).ready(function($) {
  $('[data-gf-field-type="checkbox_radio"] input[type="checkbox"],' +
    '[data-gf-field-type="checkbox_radio"] input[type="radio"],' +
    '[data-gf-field-type="terms_conditions"] input[type="checkbox"]').each(function() {
    var $input = $(this);
    var styles = window.getComputedStyle($input[0]);

    // Get accent-color from computed styles (set by theme CSS)
    var accentColor = styles.accentColor;

    // If accent-color is set and not 'auto', apply it directly
    if (accentColor && accentColor !== 'auto' && accentColor !== 'rgba(0, 0, 0, 0)') {
      $input[0].style.setProperty('accent-color', accentColor, 'important');
    }
  });
});

/**
 * Style file upload ::file-selector-button to match theme
 * Applies minimal styling to make the button blend with the form theme
 */
jQuery(document).ready(function(jq) {
  jq('[data-gf-field-type="file_upload"] input[type="file"]').each(function() {
    var fileInput = jq(this);
    var styles = window.getComputedStyle(fileInput[0]);
    var elem = fileInput[0];

    // Get border and text color from the input
    var borderColor = styles.borderColor || styles.borderTopColor;
    var textColor = styles.color;
    var borderWidth = styles.borderWidth || styles.borderTopWidth;
    var borderStyle = styles.borderStyle || styles.borderTopStyle;
    var borderRadius = styles.borderRadius || styles.borderTopLeftRadius;

    // Create semi-transparent background from border color (like input-group spans)
    var backgroundColor = 'transparent';
    var rgbaMatch = borderColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*[\d.]+)?\)/);
    if (rgbaMatch) {
      var r = rgbaMatch[1];
      var g = rgbaMatch[2];
      var b = rgbaMatch[3];
      backgroundColor = 'rgba(' + r + ', ' + g + ', ' + b + ', 0.1)';
    }

    // Create slightly darker background for hover (20% opacity instead of 10%)
    var hoverBackground = 'transparent';
    if (rgbaMatch) {
      var r = rgbaMatch[1];
      var g = rgbaMatch[2];
      var b = rgbaMatch[3];
      hoverBackground = 'rgba(' + r + ', ' + g + ', ' + b + ', 0.2)';
    }

    // Apply styles to ::file-selector-button using CSS custom properties
    // These will be picked up by the ::file-selector-button pseudo-element
    elem.style.setProperty('--file-button-border-color', borderColor);
    elem.style.setProperty('--file-button-text-color', textColor);
    elem.style.setProperty('--file-button-border-width', borderWidth);
    elem.style.setProperty('--file-button-border-style', borderStyle);
    elem.style.setProperty('--file-button-border-radius', borderRadius);
    elem.style.setProperty('--file-button-background-color', backgroundColor);
    elem.style.setProperty('--file-button-hover-bg', hoverBackground);

    // Create a style element for ::file-selector-button if it doesn't exist
    var styleId = 'gf-file-button-styles';
    if (!document.getElementById(styleId)) {
      var style = document.createElement('style');
      style.id = styleId;
      style.textContent =
        '[data-gf-field-type="file_upload"] input[type="file"]::file-selector-button {' +
          'padding: 0.375rem 0.75rem;' +
          'margin-left: -8px;' +
          'margin-right: 0.5rem;' +
          'color: var(--file-button-text-color, #212529) !important;' +
          'background-color: var(--file-button-background-color, transparent);' +
          'border: var(--file-button-border-width, 1px) var(--file-button-border-style, solid) var(--file-button-border-color, #dee2e6);' +
          'border-radius: var(--file-button-border-radius, 0.25rem);' +
          'cursor: pointer;' +
          'transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;' +
        '}' +
        '[data-gf-field-type="file_upload"] input[type="file"]::file-selector-button:hover {' +
          'background-color: var(--file-button-hover-bg, rgba(0, 0, 0, 0.1)) !important;' +
        '}';
      document.head.appendChild(style);
    }
  });
});

jQuery(document).ready(function(jq) {
  function buildChevronDataUri(strokeColor) {
    var safeColor = strokeColor || '#6c757d';
    var svg = "<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><polyline points='2,4 6,8 10,4' fill='none' stroke='" + safeColor + "' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/></svg>";
    return 'url(\"data:image/svg+xml,' + encodeURIComponent(svg) + '\")';
  }

  jq('.griffinforms-phone-input-group').each(function() {
    var group = jq(this);
    var input = group.find('input[type="tel"]').first();
    var select = group.find('select.griffinforms-phone-country-select').first();

    if (!input.length || !select.length) {
      return;
    }

    var styles = window.getComputedStyle(input[0]);
    select[0].style.setProperty('color', styles.color, 'important');
    select[0].style.setProperty('--gf-phone-caret-image', buildChevronDataUri(styles.color));
  });
});

/**
 * Responsive class manager
 * Adds gf-xs/gf-sm/gf-md/gf-lg to the outer form wrapper based on actual width.
 */
(function() {
  var BREAKPOINTS = {
    xs: 480,
    sm: 768,
    md: 992
  };
  var CLASS_LIST = ['gf-xs', 'gf-sm', 'gf-md', 'gf-lg'];
  var fallbackWrappers = new Set();
  var fallbackHandlerAttached = false;

  function getClassForWidth(width) {
    if (width < BREAKPOINTS.xs) {
      return 'gf-xs';
    }
    if (width < BREAKPOINTS.sm) {
      return 'gf-sm';
    }
    if (width < BREAKPOINTS.md) {
      return 'gf-md';
    }
    return 'gf-lg';
  }

  function applyClass(el) {
    var width = el.getBoundingClientRect().width || el.offsetWidth || 0;
    var targetClass = getClassForWidth(width);
    CLASS_LIST.forEach(function(cls) {
      el.classList.remove(cls);
    });
    el.classList.add(targetClass);

    updatePaymentGrid(el, targetClass);
  }

  function initWrapper(el) {
    if (el.__gfResponsiveInitialized) {
      return;
    }
    el.__gfResponsiveInitialized = true;
    applyClass(el);

    if (window.ResizeObserver) {
      var rafScheduled = false;
      var observer = new ResizeObserver(function() {
        if (rafScheduled) {
          return;
        }
        rafScheduled = true;
        window.requestAnimationFrame(function() {
          applyClass(el);
          rafScheduled = false;
        });
      });
      observer.observe(el);
      el.__gfResponsiveObserver = observer;
    } else {
      fallbackWrappers.add(el);
      if (!fallbackHandlerAttached) {
        fallbackHandlerAttached = true;
        var throttled = throttle(function() {
          fallbackWrappers.forEach(applyClass);
        }, 150);
        window.addEventListener('resize', throttled);
      }
    }
  }

  function throttle(fn, wait) {
    var timeout = null;
    return function() {
      if (timeout) {
        return;
      }
      timeout = setTimeout(function() {
        timeout = null;
        fn();
      }, wait);
    };
  }

  function findWrappers() {
    var nodes = document.querySelectorAll('[data-gf-form-id]');
    return Array.prototype.filter.call(nodes, function(node) {
      var className = node.className || '';
      return className.indexOf('griffinforms-form') !== -1 && className.indexOf('-container') !== -1;
    });
  }

  function initAllWrappers() {
    findWrappers().forEach(initWrapper);
  }

  document.addEventListener('DOMContentLoaded', initAllWrappers);
  window.addEventListener('griffinformsFormLoaded', initAllWrappers);
})();

function updatePaymentGrid(wrapper, breakpointClass) {
  var layoutMap = {
    'gf-xs': 1,
    'gf-sm': 1,
    'gf-md': 2,
    'gf-lg': 3
  };

  breakpointClass = breakpointClass || 'gf-lg';
  var columns = layoutMap[breakpointClass] || 3;

  var grids = wrapper.querySelectorAll('.griffinforms-payment-field-group[data-gf-layout="cards"]');
  if (!grids || !grids.length) {
    return;
  }

  grids.forEach(function(grid) {
    grid.style.setProperty('--griffinforms-grid-columns', columns);
  });
}

/**
 * Style griffinforms-phone-input-group elements to match themed input fields
 * Handles first element, last element, and input field positioning intelligently
 */
jQuery(document).ready(function(jq) {
  // Helper function to convert kebab-case CSS property to camelCase JavaScript property
  function cssPropertyToCamelCase(cssProp) {
    return cssProp.replace(/-([a-z])/g, function(_, letter) {
      return letter.toUpperCase();
    });
  }

  jq('.griffinforms-phone-input-group').each(function() {
    var group = jq(this);
    var children = group.children();
    var inputElem = group.find('input[type="tel"]').first();
    if (!inputElem.length) {
      inputElem = group.find('input, select, textarea').first();
    }

    if (!inputElem.length || children.length < 2) return;

    var styles = window.getComputedStyle(inputElem[0]);
    var inputIndex = children.index(inputElem);
    var firstChild = children.first();
    var lastChild = children.last();
    var hasElementBefore = inputIndex > 0;
    var hasElementAfter = inputIndex < children.length - 1;

    // Check if input has minimal styling (bottom border only, no radius)
    // This pattern is common for underlined/minimal input themes
    var hasTopBorder = parseFloat(styles.borderTopWidth) > 0;
    var hasLeftBorder = parseFloat(styles.borderLeftWidth) > 0;
    var hasRadius = parseFloat(styles.borderTopLeftRadius) > 0 || parseFloat(styles.borderTopRightRadius) > 0;
    var isMinimalStyle = !hasTopBorder && !hasLeftBorder && !hasRadius;

    // Helper function to apply border styles to an element
    function applyBorderStyles(element, sides) {
      var elem = element[0];
      var borderProps = ['Width', 'Style', 'Color'];
      var radiusMap = {
        'left': ['border-top-left-radius', 'border-bottom-left-radius'],
        'right': ['border-top-right-radius', 'border-bottom-right-radius']
      };

      // Apply border properties for specified sides
      jq.each(sides.borders, function(i, side) {
        var capitalSide = side.charAt(0).toUpperCase() + side.slice(1);
        jq.each(borderProps, function(j, prop) {
          var cssProp = 'border-' + side + '-' + prop.toLowerCase();
          var value = styles['border' + capitalSide + prop];

          // Only apply if value is not 'none' or '0px' (skip absent borders)
          if (value && value !== 'none' && parseFloat(value) !== 0) {
            elem.style.setProperty(cssProp, value, 'important');
          }
        });
      });

      // Zero out opposite borders
      jq.each(sides.zeroBorders, function(i, side) {
        elem.style.setProperty('border-' + side + '-width', '0', 'important');
        elem.style.setProperty('border-' + side + '-style', 'none', 'important');
      });

      // Skip radius styling for minimal (bottom-border-only) themes
      if (!isMinimalStyle) {
        // Apply border radius
        jq.each(sides.radius, function(i, side) {
          jq.each(radiusMap[side], function(j, radiusProp) {
            var camelCaseProperty = cssPropertyToCamelCase(radiusProp);
            var value = styles[camelCaseProperty];
            if (value && value !== 'none' && parseFloat(value) !== 0) {
              elem.style.setProperty(radiusProp, value, 'important');
            }
          });
        });

        // Zero out opposite radius
        jq.each(sides.zeroRadius, function(i, side) {
          jq.each(radiusMap[side], function(j, radiusProp) {
            elem.style.setProperty(radiusProp, '0', 'important');
          });
        });
      }

      // Copy text color
      elem.style.setProperty('color', styles.color, 'important');

      // Set background to semi-transparent version of border color (for non-input elements)
      // Skip background for minimal style themes and for select elements (use theme CSS instead)
      if (elem !== inputElem[0] && !isMinimalStyle && elem.tagName !== 'SELECT') {
        var borderColor = styles.borderTopColor;
        var rgbaMatch = borderColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*[\d.]+)?\)/);
        if (rgbaMatch) {
          var r = rgbaMatch[1];
          var g = rgbaMatch[2];
          var b = rgbaMatch[3];
          elem.style.setProperty('background-color', 'rgba(' + r + ', ' + g + ', ' + b + ', 0.1)', 'important');
        }
      }
    }

    // Style first element if it's not the input
    if (firstChild[0] !== inputElem[0]) {
      // For minimal style, remove all borders/background - keep only text color
      if (isMinimalStyle) {
        var elem = firstChild[0];
        elem.style.setProperty('border', 'none', 'important');
        elem.style.setProperty('background', 'transparent', 'important');
        elem.style.setProperty('color', styles.color, 'important');
      } else {
        applyBorderStyles(firstChild, {
          borders: ['top', 'bottom', 'left'],
          zeroBorders: ['right'],
          radius: ['left'],
          zeroRadius: ['right']
        });
        if (firstChild[0].tagName === 'SELECT') {
          var borderWidth = styles.borderRightWidth;
          var borderStyle = styles.borderRightStyle;
          var borderColor = styles.borderRightColor;
          var fallbackColor = borderColor || styles.borderTopColor || styles.borderColor;
          if (fallbackColor) {
            firstChild[0].style.setProperty('--gf-phone-border-color', fallbackColor);
          }
          if (borderWidth && parseFloat(borderWidth) > 0 && borderStyle && borderStyle !== 'none') {
            firstChild[0].style.setProperty('--gf-phone-border-width', borderWidth);
            firstChild[0].style.setProperty('--gf-phone-border-style', borderStyle);
            firstChild[0].style.setProperty('--gf-phone-border-color', borderColor);
            firstChild[0].style.setProperty('border-right-width', borderWidth, 'important');
            firstChild[0].style.setProperty('border-right-style', borderStyle, 'important');
            firstChild[0].style.setProperty('border-right-color', borderColor, 'important');
          } else if (borderStyle && borderStyle !== 'none') {
            firstChild[0].style.setProperty('border-right-width', '1px', 'important');
            firstChild[0].style.setProperty('border-right-style', borderStyle, 'important');
            if (fallbackColor) {
              firstChild[0].style.setProperty('border-right-color', fallbackColor, 'important');
              firstChild[0].style.setProperty('box-shadow', 'inset -1px 0 0 ' + fallbackColor, 'important');
            }
          }
        }
      }
    }

    // Style last element if it's not the input
    if (lastChild[0] !== inputElem[0] && lastChild[0] !== firstChild[0]) {
      // For minimal style, remove all borders/background - keep only text color
      if (isMinimalStyle) {
        var elem = lastChild[0];
        elem.style.setProperty('border', 'none', 'important');
        elem.style.setProperty('background', 'transparent', 'important');
        elem.style.setProperty('color', styles.color, 'important');
      } else {
        applyBorderStyles(lastChild, {
          borders: ['top', 'bottom', 'right'],
          zeroBorders: ['left'],
          radius: ['right'],
          zeroRadius: ['left']
        });
      }
    }

    // Style input field based on its position
    var inputDom = inputElem[0];
    if (hasElementBefore && hasElementAfter) {
      // Input has elements on both sides - zero all borders
      inputDom.style.setProperty('border-left-width', '0', 'important');
      inputDom.style.setProperty('border-right-width', '0', 'important');
      inputDom.style.setProperty('border-left-style', 'none', 'important');
      inputDom.style.setProperty('border-right-style', 'none', 'important');
      inputDom.style.setProperty('border-top-left-radius', '0', 'important');
      inputDom.style.setProperty('border-bottom-left-radius', '0', 'important');
      inputDom.style.setProperty('border-top-right-radius', '0', 'important');
      inputDom.style.setProperty('border-bottom-right-radius', '0', 'important');
    } else if (hasElementBefore) {
      // Input has element before - zero left radius only
      inputDom.style.setProperty('border-left-width', '0', 'important');
      inputDom.style.setProperty('border-left-style', 'none', 'important');
      inputDom.style.setProperty('border-top-left-radius', '0', 'important');
      inputDom.style.setProperty('border-bottom-left-radius', '0', 'important');
    } else if (hasElementAfter) {
      // Input has element after - zero right border
      inputDom.style.setProperty('border-right-width', '0', 'important');
      inputDom.style.setProperty('border-right-style', 'none', 'important');
      inputDom.style.setProperty('border-top-right-radius', '0', 'important');
      inputDom.style.setProperty('border-bottom-right-radius', '0', 'important');
    }
  });
});

/**
 * Style griffinforms-password-input-group elements to match themed input fields
 * Handles password input with toggle button on the right side
 */
jQuery(document).ready(function($) {
  // Helper function to convert kebab-case CSS property to camelCase JavaScript property
  function cssPropertyToCamelCase(cssProp) {
    return cssProp.replace(/-([a-z])/g, function(_, letter) {
      return letter.toUpperCase();
    });
  }

  $('.griffinforms-password-input-group').each(function() {
    var group = $(this);
    var children = group.children();
    var inputElem = group.find('input[type="password"], input[type="text"]').first();
    var buttonElem = group.find('button').first();

    if (!inputElem.length || !buttonElem.length) return;

    var styles = window.getComputedStyle(inputElem[0]);
    var inputIndex = children.index(inputElem);
    var firstChild = children.first();
    var lastChild = children.last();

    // Check if input has minimal styling (bottom border only, no radius)
    var hasTopBorder = parseFloat(styles.borderTopWidth) > 0;
    var hasLeftBorder = parseFloat(styles.borderLeftWidth) > 0;
    var hasRadius = parseFloat(styles.borderTopLeftRadius) > 0 || parseFloat(styles.borderTopRightRadius) > 0;
    var isMinimalStyle = !hasTopBorder && !hasLeftBorder && !hasRadius;

    // Helper function to apply border styles to button element
    function applyButtonBorderStyles(element, sides) {
      var elem = element[0];
      var borderProps = ['Width', 'Style', 'Color'];
      var radiusMap = {
        'left': ['border-top-left-radius', 'border-bottom-left-radius'],
        'right': ['border-top-right-radius', 'border-bottom-right-radius']
      };

      // For color property, use the most prominent border color
      var reliableBorderColor = styles.borderTopColor || styles.borderBottomColor || styles.borderColor;

      // Apply border properties for specified sides
      $.each(sides.borders, function(i, side) {
        var capitalSide = side.charAt(0).toUpperCase() + side.slice(1);
        $.each(borderProps, function(j, prop) {
          var cssProp = 'border-' + side + '-' + prop.toLowerCase();
          var value = styles['border' + capitalSide + prop];

          // Special handling for Color: use reliable border color instead of side-specific
          if (prop === 'Color') {
            value = reliableBorderColor;
          }

          // Only apply if value is not 'none' or '0px'
          if (value && value !== 'none' && parseFloat(value) !== 0) {
            elem.style.setProperty(cssProp, value, 'important');
          }
        });
      });

      // Zero out opposite borders
      $.each(sides.zeroBorders, function(i, side) {
        elem.style.setProperty('border-' + side + '-width', '0', 'important');
        elem.style.setProperty('border-' + side + '-style', 'none', 'important');
      });

      // Skip radius styling for minimal (bottom-border-only) themes
      if (!isMinimalStyle) {
        // Apply border radius
        $.each(sides.radius, function(i, side) {
          $.each(radiusMap[side], function(j, radiusProp) {
            var camelCaseProperty = cssPropertyToCamelCase(radiusProp);
            var value = styles[camelCaseProperty];
            if (value && value !== 'none' && parseFloat(value) !== 0) {
              elem.style.setProperty(radiusProp, value, 'important');
            }
          });
        });

        // Zero out opposite radius
        $.each(sides.zeroRadius, function(i, side) {
          $.each(radiusMap[side], function(j, radiusProp) {
            elem.style.setProperty(radiusProp, '0', 'important');
          });
        });
      }

      // Copy text color
      elem.style.setProperty('color', styles.color, 'important');

      // Set background to semi-transparent version of border color
      if (!isMinimalStyle) {
        var borderColor = styles.borderTopColor;
        var rgbaMatch = borderColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*[\d.]+)?\)/);
        if (rgbaMatch) {
          var r = rgbaMatch[1];
          var g = rgbaMatch[2];
          var b = rgbaMatch[3];
          elem.style.setProperty('background-color', 'rgba(' + r + ', ' + g + ', ' + b + ', 0.1)', 'important');
        }
      }
    }

    // Style button (on the right side)
    if (isMinimalStyle) {
      var elem = buttonElem[0];
      elem.style.setProperty('border', 'none', 'important');
      elem.style.setProperty('background', 'transparent', 'important');
      elem.style.setProperty('color', styles.color, 'important');
    } else {
      applyButtonBorderStyles(buttonElem, {
        borders: ['top', 'bottom', 'right'],
        zeroBorders: ['left'],
        radius: ['right'],
        zeroRadius: ['left']
      });
    }

    // Style input field - zero right radius only (button provides visual continuity)
    var inputDom = inputElem[0];
    inputDom.style.setProperty('border-top-right-radius', '0', 'important');
    inputDom.style.setProperty('border-bottom-right-radius', '0', 'important');
  });
});
