<div class="{{ block.settings.visibility }}"
  id="blinking-dot-{{ section.id }}-{{ block.id }}"
  {{ block.shopify_attributes }}
  style="--margin-top: {{ block.settings.margin_top | divided_by: 10.0 }}rem;--margin-bottom: {{ block.settings.margin_bottom | divided_by: 10.0 }}rem; display: {% if block.settings.variant_option_names != blank %}none{% else %}block{% endif %};"
>
  <div class="blinkingdot_text blinkingdot_text-{{ section.id }}-{{ block.id }} text-center">
    <dynamic-dates
      style="font-size:{{ block.settings.dot_textsize }}px;"
      class="estimated-shipping"
      data-date-format="{{ block.settings.date_format }}"
      data-day-labels="{{ block.settings.days_labels }}"
      data-month-labels="{{ block.settings.months_labels }}"
      data-skip-weekdays="{{ block.settings.skip_weekdays }}"
      data-skip-dates="{{ block.settings.skip_specific_dates }}"
    >
      {%- comment -%}
        Hidden template element — stores the raw richtext HTML for JS to read.
        Never visible to the user. Avoids the [end_date] flash that occurs when
        rendering the template directly into the visible span.
      {%- endcomment -%}
      <template id="blinking-dot-template-{{ section.id }}-{{ block.id }}">{{- block.settings.dot_text -}}</template>

      <span
        class="estimated-shipping__text"
        style="margin:auto; display:{{ block.settings.blinktext_align }}; visibility: hidden;"
        data-dynamic-date="true"
        data-min-days="{{ block.settings.min_shipping_days }}"
        data-max-days="{{ block.settings.max_shipping_days }}"
        data-enable-badge="{{ block.settings.enable_date_badge }}"
        data-template-id="blinking-dot-template-{{ section.id }}-{{ block.id }}"
      ></span></dynamic-dates
    >
  </div>
</div>

<script>
(function() {
  function initBlinkingDotVariants() {
    const blinkingDotElement = document.getElementById('blinking-dot-{{ section.id }}-{{ block.id }}');
    if (!blinkingDotElement) return;
    
    const optionNamesString = "{{ block.settings.variant_option_names | default: '' }}";
    const optionValuesString = "{{ block.settings.variant_option_values | default: '' }}";
    
    if (!optionNamesString.trim()) {
      blinkingDotElement.style.display = 'block';
      return;
    }
    
    const optionNames = optionNamesString.split(',').map(name => name.trim().toLowerCase());
    const optionValues = optionValuesString.split(',').map(value => value.trim().toLowerCase());
    
    function checkAndUpdateVisibility() {
      let shouldShow = false;
      
      for (let i = 0; i < optionNames.length; i++) {
        const optionName = optionNames[i];
        if (!optionName) continue;
        
        let selectedValue = null;
        
        const selectors = [
          `select[name="options[${optionName}]"]`,
          `select[name="${optionName}"]`,
          `input[type="radio"][name="options[${optionName}]"]:checked`,
          `input[type="radio"][name="${optionName}"]:checked`
        ];
        
        for (let selector of selectors) {
          const element = document.querySelector(selector);
          if (element && element.value) {
            selectedValue = element.value.toLowerCase().trim();
            break;
          }
        }
        
        if (!selectedValue) {
          const variantContainer = document.querySelector('#variant-selects-{{ section.id }}');
          if (variantContainer) {
            const allCheckedInputs = variantContainer.querySelectorAll('input:checked');
            allCheckedInputs.forEach(function(input) {
              if (input.name && input.name.toLowerCase().includes(optionName)) {
                selectedValue = input.value.toLowerCase().trim();
              }
            });
          }
        }
        
        if (selectedValue) {
          for (let j = 0; j < optionValues.length; j++) {
            if (optionValues[j] && selectedValue === optionValues[j]) {
              shouldShow = true;
              break;
            }
          }
        }
        
        if (shouldShow) break;
      }
      
      blinkingDotElement.style.display = shouldShow ? 'block' : 'none';
    }
    
    checkAndUpdateVisibility();
    
    const variantSelector = document.querySelector('#variant-selects-{{ section.id }}');
    if (variantSelector) {
      variantSelector.addEventListener('change', checkAndUpdateVisibility);
    }
    
    const productForm = document.querySelector('form[action*="/cart/add"]');
    if (productForm) {
      productForm.addEventListener('change', checkAndUpdateVisibility);
    }
    
    document.addEventListener('variant:change', checkAndUpdateVisibility);
    
    if (window.Shopify && window.Shopify.designMode) {
      document.addEventListener('shopify:section:load', function(event) {
        if (event.detail.sectionId === '{{ section.id }}') {
          setTimeout(checkAndUpdateVisibility, 100);
        }
      });
      document.addEventListener('shopify:block:select', function(event) {
        if (event.detail.sectionId === '{{ section.id }}') {
          setTimeout(checkAndUpdateVisibility, 100);
        }
      });
    }
  }
  
  document.addEventListener('DOMContentLoaded', initBlinkingDotVariants);
  if (document.readyState === 'complete' || document.readyState === 'interactive') {
    initBlinkingDotVariants();
  }

  // Re-check visibility whenever the cart drawer's contents get swapped by an
  // AJAX cart update (add to cart, quantity change, gift/sub toggles, etc).
  // There's no single JS hook for that, so we watch the DOM instead.
  window.__blinkingDotCallbacks = window.__blinkingDotCallbacks || [];
  window.__blinkingDotCallbacks.push(initBlinkingDotVariants);

  if (!window.__blinkingDotObserverInit && window.MutationObserver) {
    window.__blinkingDotObserverInit = true;
    var _bdTarget = document.getElementById('CartDrawer') || document.body;
    var _bdDebounce;
    var _bdObserver = new MutationObserver(function() {
      clearTimeout(_bdDebounce);
      _bdDebounce = setTimeout(function() {
        (window.__blinkingDotCallbacks || []).forEach(function(fn) { fn(); });
        (window.__dynamicDateCallbacks || []).forEach(function(fn) { fn(); });
      }, 50);
    });
    _bdObserver.observe(_bdTarget, { childList: true, subtree: true });
  }
})();

// Dynamic date calculation with skip days
(function() {
  function initializeDynamicDates() {
    const dateElements = document.querySelectorAll('[data-dynamic-date="true"]');
    
    dateElements.forEach(function(element) {
      const parentElement = element.closest('dynamic-dates');
      if (!parentElement) return;
      
      const minDays = parseInt(element.getAttribute('data-min-days')) || 0;
      const maxDays = parseInt(element.getAttribute('data-max-days')) || 0;

      // Read the template element — never rendered visibly, no flash
      const templateId = element.getAttribute('data-template-id');
      const templateEl = document.getElementById(templateId);
      if (!templateEl) return;
      const messageTemplate = templateEl.innerHTML;
      if (!messageTemplate) return;
      
      const dateFormat = parentElement.getAttribute('data-date-format');
      const dayLabels = parentElement.getAttribute('data-day-labels').split(',').map(s => s.trim());
      const monthLabels = parentElement.getAttribute('data-month-labels').split(',').map(s => s.trim());
      
      const skipWeekdays = parentElement.getAttribute('data-skip-weekdays') || '';
      const skipDates = parentElement.getAttribute('data-skip-dates') || '';
      
      const dayNameMap = {
        'sunday': 0, 'sun': 0,
        'monday': 1, 'mon': 1,
        'tuesday': 2, 'tue': 2, 'tues': 2,
        'wednesday': 3, 'wed': 3,
        'thursday': 4, 'thu': 4, 'thur': 4, 'thurs': 4,
        'friday': 5, 'fri': 5,
        'saturday': 6, 'sat': 6
      };
      
      const skipWeekdaysArray = skipWeekdays 
        ? skipWeekdays.split(',').map(d => d.trim().toLowerCase()).map(d => dayNameMap[d]).filter(d => d !== undefined)
        : [];
      
      const skipDatesArray = skipDates 
        ? skipDates.split(',').map(d => d.trim()).filter(d => d) 
        : [];
      
      function shouldSkipDate(date) {
        if (skipWeekdaysArray.includes(date.getDay())) return true;
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, '0');
        const day = String(date.getDate()).padStart(2, '0');
        return skipDatesArray.includes(year + '-' + month + '-' + day);
      }
      
      function addBusinessDays(startDate, daysToAdd) {
        let currentDate = new Date(startDate.getTime());
        let daysAdded = 0;
        while (daysAdded < daysToAdd) {
          currentDate.setDate(currentDate.getDate() + 1);
          if (!shouldSkipDate(currentDate)) daysAdded++;
        }
        return currentDate;
      }
      
      const today = new Date();
      const startDate = addBusinessDays(today, minDays);
      const endDate = addBusinessDays(today, maxDays);
      
      function formatDate(date, format) {
        const day = date.getDate();
        const month = date.getMonth();
        const dayOfWeek = date.getDay();
        
        function getOrdinalSuffix(d) {
          if (d > 3 && d < 21) return 'th';
          switch (d % 10) {
            case 1: return 'st';
            case 2: return 'nd';
            case 3: return 'rd';
            default: return 'th';
          }
        }
        
        const dayWithSuffix = day + getOrdinalSuffix(day);
        const paddedDay = String(day).padStart(2, '0');
        const paddedMonth = String(month + 1).padStart(2, '0');
        
        switch(format) {
          case 'day_mm_dd': return dayLabels[dayOfWeek] + ', ' + monthLabels[month] + ' ' + dayWithSuffix;
          case 'day_dd_mm': return dayLabels[dayOfWeek] + ', ' + day + '. ' + monthLabels[month];
          case 'mm_dd':     return monthLabels[month] + ' ' + dayWithSuffix;
          case 'month_day': return monthLabels[month] + ' ' + day;
          case 'dd_mm':     return day + '. ' + monthLabels[month];
          case 'dd_mm_no_dot': return day + ' ' + monthLabels[month];
          case 'day_dd_mm_numeric': return dayLabels[dayOfWeek] + ', ' + paddedDay + '. ' + paddedMonth + '.';
          case 'dd_mm_numeric': return paddedDay + '. ' + paddedMonth + '.';
          default: return monthLabels[month] + ' ' + dayWithSuffix;
        }
      }
      
      const startDateFormatted = formatDate(startDate, dateFormat);
      const endDateFormatted = formatDate(endDate, dateFormat);

      const enableBadge = element.getAttribute('data-enable-badge') === 'true';

      function wrapBadge(dateStr) {
        if (!enableBadge) return dateStr;
        return '<span class="estimated-shipping__date-badge">' + dateStr + '</span>';
      }

      const finalMessage = messageTemplate
        .replace(/\[start_date\]/g, wrapBadge(startDateFormatted))
        .replace(/\[end_date\]/g, wrapBadge(endDateFormatted));
      
      element.innerHTML = finalMessage;

      // Apply underline wrapping
      const enableUnderline = {{ block.settings.enable_underline | json }};
      const underlineText = {{ block.settings.underline_text | json }};
      if (enableUnderline && underlineText) {
        const escaped = underlineText.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        element.innerHTML = element.innerHTML.replace(
          new RegExp(escaped, 'g'),
          '<span class="blinkingdot__underline">' + underlineText + '</span>'
        );
      }

      // Make inner <p> flex so badge pill sits inline with text
      if (enableBadge) {
        const innerP = element.querySelector('p');
        if (innerP) {
          innerP.style.display = 'inline-flex';
          innerP.style.alignItems = 'center';
          innerP.style.gap = '4px';
          innerP.style.flexWrap = 'wrap';
        }
      }

      // Reveal now that content is ready — no flash
      element.style.visibility = 'visible';
    });
  }
  
  document.addEventListener('DOMContentLoaded', initializeDynamicDates);
  if (document.readyState === 'complete' || document.readyState === 'interactive') {
    initializeDynamicDates();
  }

  // Re-run whenever the cart drawer's contents get swapped — shares the same
  // MutationObserver registered above.
  window.__dynamicDateCallbacks = window.__dynamicDateCallbacks || [];
  window.__dynamicDateCallbacks.push(initializeDynamicDates);
})();
</script>

<style>
  #blinking-dot-{{ section.id }}-{{ block.id }} .blinkingdot_text p:before {
      position: relative;
      display: inline-block;
      content: "";
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background-color: {{ block.settings.dot_color }};
      margin-right: 10px;
      animation: blink-{{ section.id }}-{{ block.id }} 1.5s infinite;
  }

  #blinking-dot-{{ section.id }}-{{ block.id }} .blinkingdot_text p {
      align-items: center;
      justify-content: {{ block.settings.blinktext_align }};
      gap: 5px;
      line-height: 1;
      width: 100%;
      flex-wrap: wrap;
      margin: 10px 0;
      position: relative;
      font-size: {{ block.settings.dot_textsize }}px;
      font-weight: 400;
      color: {{ block.settings.dot_textcolor }};
  }

  @keyframes blink-{{ section.id }}-{{ block.id }} {
      0%   { opacity: 1; }
      50%  { opacity: 0.5; }
      100% { opacity: 1; }
  }

{% if block.settings.dot_textbackground %}
  {% if block.settings.enable_custom_padding %}
    {% if block.settings.blinktext_align == 'contents' %}
      #blinking-dot-{{ section.id }}-{{ block.id }} .blinkingdot_text {
        background: {{ block.settings.dot_textcolorbackground }};
        border: {{ block.settings.dot_textcborderthickness }}px {{ block.settings.border_style | default: 'dotted' }} {{ block.settings.dot_textcolorbackgroundborder }};
        border-radius: {{ block.settings.dot_textcolorbackgroundradius }}px;
        padding: {{ block.settings.vertical_padding }}px {{ block.settings.horizontal_padding }}px;
        display: inline-block;
        width: fit-content;
      }
    {% else %}
      #blinking-dot-{{ section.id }}-{{ block.id }} .blinkingdot_text {
        text-align: center;
      }
      #blinking-dot-{{ section.id }}-{{ block.id }} .blinkingdot_text .estimated-shipping {
        background: {{ block.settings.dot_textcolorbackground }};
        border: {{ block.settings.dot_textcborderthickness }}px {{ block.settings.border_style | default: 'dotted' }} {{ block.settings.dot_textcolorbackgroundborder }};
        border-radius: {{ block.settings.dot_textcolorbackgroundradius }}px;
        padding: {{ block.settings.vertical_padding }}px {{ block.settings.horizontal_padding }}px;
        display: inline-block;
      }
    {% endif %}
  {% else %}
    {% if block.settings.blinktext_align == 'contents' %}
      #blinking-dot-{{ section.id }}-{{ block.id }} .blinkingdot_text {
        background: {{ block.settings.dot_textcolorbackground }};
        border: {{ block.settings.dot_textcborderthickness }}px {{ block.settings.border_style | default: 'dotted' }} {{ block.settings.dot_textcolorbackgroundborder }};
        border-radius: {{ block.settings.dot_textcolorbackgroundradius }}px;
        padding: 10px 10px 2px 10px;
        display: inline-block;
        width: fit-content;
      }
    {% else %}
      #blinking-dot-{{ section.id }}-{{ block.id }} .blinkingdot_text {
        background: {{ block.settings.dot_textcolorbackground }};
        border: {{ block.settings.dot_textcborderthickness }}px {{ block.settings.border_style | default: 'dotted' }} {{ block.settings.dot_textcolorbackgroundborder }};
        border-radius: {{ block.settings.dot_textcolorbackgroundradius }}px;
        padding-top: 8px;
        padding-bottom: 8px;
      }
    {% endif %}
  {% endif %}
{% endif %}

{% if block.settings.enable_date_badge %}
  #blinking-dot-{{ section.id }}-{{ block.id }} .estimated-shipping__date-badge {
    display: inline-block;
    background-color: {{ block.settings.date_badge_bg }};
    color: {{ block.settings.date_badge_text_color }};
    border-radius: {{ block.settings.date_badge_radius }}px;
    padding: 1px 8px;
    font-weight: 600;
    line-height: 1.5;
    vertical-align: middle;
    white-space: nowrap;
  }
{% endif %}

{% if block.settings.enable_underline and block.settings.underline_text != blank %}
  #blinking-dot-{{ section.id }}-{{ block.id }} .blinkingdot__underline {
    text-decoration: underline;
    text-decoration-color: {{ block.settings.underline_color }};
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
  }
{% endif %}

</style>