(function ($) {
  'use strict';

  function escapeHtml(value) {
    return $('<div>').text(value || '').html();
  }

  function galleryForForm($form) {
    var $product = $form.closest('.product');
    var $gallery = $product.find('.woocommerce-product-gallery').first();
    if (!$gallery.length) {
      $gallery = $('.woocommerce-product-gallery').first();
    }
    return $gallery;
  }

  function ensureOriginal($gallery) {
    if (!$gallery.length || $gallery.data('niwaOriginalGalleryHtml')) {
      return;
    }
    var $wrapper = $gallery.find('.woocommerce-product-gallery__wrapper').first();
    if ($wrapper.length) {
      $gallery.data('niwaOriginalGalleryHtml', $wrapper.html());
    }
  }

  function attr(name, value) {
    if (!value) {
      return '';
    }
    return ' ' + name + '="' + escapeHtml(String(value)) + '"';
  }

  function imageMarkup(image, index) {
    var full = image && image.full_src ? String(image.full_src) : '';
    if (!full) {
      return '';
    }
    var thumb = image.thumb_src ? String(image.thumb_src) : full;
    var alt = image.alt ? String(image.alt) : '';
    var title = image.title ? String(image.title) : alt;
    var width = image.full_w ? String(image.full_w) : '';
    var height = image.full_h ? String(image.full_h) : '';

    return [
      '<div data-thumb="' + escapeHtml(thumb) + '" data-thumb-alt="' + escapeHtml(alt) + '" class="woocommerce-product-gallery__image">',
      '<a href="' + escapeHtml(full) + '">',
      '<img src="' + escapeHtml(full) + '"' +
        attr('width', width) +
        attr('height', height) +
        attr('alt', alt) +
        attr('title', title) +
        ' data-caption=""' +
        attr('data-src', full) +
        attr('data-large_image', full) +
        attr('data-large_image_width', width) +
        attr('data-large_image_height', height) +
        attr('srcset', image.srcset) +
        attr('sizes', image.sizes) +
        (index === 0 ? ' loading="eager"' : ' loading="lazy"') +
      ' />',
      '</a>',
      '</div>',
    ].join('');
  }

  function renderVariationGallery($form, variation) {
    var payload = variation && variation.niwa_variation_gallery ? variation.niwa_variation_gallery : null;
    var images = payload && Array.isArray(payload.images) ? payload.images : [];
    if (images.length < 2) {
      return;
    }

    var $gallery = galleryForForm($form);
    var $wrapper = $gallery.find('.woocommerce-product-gallery__wrapper').first();
    if (!$wrapper.length) {
      return;
    }

    ensureOriginal($gallery);

    var html = images.map(imageMarkup).join('');
    if (!html) {
      return;
    }

    $wrapper.html(html);
    $gallery.trigger('woocommerce_gallery_reset_slide_position');
    $(document.body).trigger('niwa_variation_gallery_rendered', [payload, $gallery]);
  }

  function selectedAttributes($form) {
    var selected = {};
    $form.find('select[name^="attribute_"]').each(function () {
      var name = String(this.name || '').replace(/^attribute_/, '');
      var value = String($(this).val() || '');
      if (name && value) {
        selected[name] = value;
      }
    });
    $form.find('input[name^="attribute_"]:checked').each(function () {
      var name = String(this.name || '').replace(/^attribute_/, '');
      var value = String($(this).val() || '');
      if (name && value) {
        selected[name] = value;
      }
    });
    return selected;
  }

  function variationMatchesSelection(variation, selected) {
    var attrs = variation && variation.attributes ? variation.attributes : {};
    var matched = 0;
    Object.keys(selected).forEach(function (name) {
      var expected = selected[name];
      var actual = attrs['attribute_' + name];
      if (actual === undefined) {
        actual = attrs[name];
      }
      if (actual === '' || actual === expected) {
        matched += 1;
      } else {
        matched = -999;
      }
    });
    return matched > 0;
  }

  function renderPartialSelectionGallery($form) {
    var selected = selectedAttributes($form);
    if (!Object.keys(selected).length) {
      restoreOriginal($form);
      return;
    }

    var variations = $form.data('product_variations') || [];
    if (!Array.isArray(variations) || !variations.length) {
      return;
    }

    for (var index = 0; index < variations.length; index += 1) {
      if (variationMatchesSelection(variations[index], selected) && variations[index].niwa_variation_gallery) {
        renderVariationGallery($form, variations[index]);
        return;
      }
    }
  }

  function restoreOriginal($form) {
    var $gallery = galleryForForm($form);
    var $wrapper = $gallery.find('.woocommerce-product-gallery__wrapper').first();
    var original = $gallery.data('niwaOriginalGalleryHtml');
    if ($wrapper.length && original) {
      $wrapper.html(original);
      $gallery.trigger('woocommerce_gallery_reset_slide_position');
    }
  }

  $(document)
    .on('found_variation', '.variations_form', function (_event, variation) {
      renderVariationGallery($(this), variation);
    })
    .on('change', '.variations_form select[name^="attribute_"], .variations_form input[name^="attribute_"]', function () {
      var $form = $(this).closest('.variations_form');
      window.setTimeout(function () {
        renderPartialSelectionGallery($form);
      }, 0);
    })
    .on('reset_data', '.variations_form', function () {
      restoreOriginal($(this));
    });
})(jQuery);
