{%- doc -%}
  Displays product images in a carousel.
  Settings allow for a full slideshow, showing only the first image, or showing the second image when hovering.
  Note: When the product card itself is in a carousel layout, the card-gallery's carousel is disabled with JavaScript.

  @param [children] - Additional content rendered below the card gallery
  @param [section] - The section object the snippet is rendered in
  @param [block] - The block object the snippet is rendered in
{%- enddoc -%}

{% liquid
  assign product = closest.product
  assign block_settings = block.settings
  assign image_sizes = '(min-width: 750px) 50vw, 100vw'

  # Check if product has badges and determine position
  assign has_badges = false
  assign badge_position = null
  if product != blank
    if product.available == false or product.compare_at_price > product.price
      assign has_badges = true
      assign badge_position = settings.badge_position
    endif
  endif

  # if the card-gallery has a section.settings.product_card_size:
  # assume grid-template autofill(card-size, 1fr) and calculate the sizes attribute based on the minimum card size
  #
  # if section has section.settings.columns:
  # assume grid-template repeat(column-count, 1fr) and calculate the sizes attribute based on the number of columns
  if section.settings.product_card_size
    capture card_size
      render 'util-product-grid-card-size', section: section
    endcapture
    assign card_size = card_size | strip | replace: 'px', '' | plus: 0
    capture sizes_attribute
      render 'util-autofill-img-size-attr', card_size: card_size, card_gap: section.settings.columns_gap_horizontal
    endcapture
    assign image_sizes = sizes_attribute | strip
  elsif section.settings.columns and section.settings.layout_type != 'editorial'
    assign viewport_width = 100.0 | divided_by: section.settings.columns
    assign sizes_attribute = '(min-width: 750px) [viewport_width]vw, 100vw' | replace: '[viewport_width]', viewport_width
    assign image_sizes = sizes_attribute | strip
  endif

  assign ratio = '1'
  case block_settings.image_ratio
    when 'landscape'
      assign ratio = '16 / 9'
    when 'portrait'
      assign ratio = '4 / 5'
    when 'square'
      assign ratio = '1'
    when 'adapt'
      assign ratio = product.featured_media.preview_image.aspect_ratio | default: '1'
  endcase

  if block_settings.image_ratio == 'adapt' and block_settings.constrain_to_viewport
    if block_settings.constrain_to_viewport != ''
      assign constrain_to_viewport = true
      assign media_fit = block_settings.constrain_to_viewport
    endif
  endif
%}

<div
  ref="cardGallery"
  class="card-gallery card-gallery-{{ block.id }} spacing-style border-style{% if has_badges %} card-gallery--badge-{{ badge_position }}{% endif %}"
  style="
    {% render 'border-override', settings: block_settings %}
    {% render 'spacing-style', settings: block_settings %}
    --gallery-aspect-ratio: {{ ratio }};
  "
  data-product-id="{{ product.id }}"
  {% if settings.show_second_image_on_hover %}
    on:pointerenter="/previewImage"
    on:pointerleave="/resetImage"
  {% endif %}
  {% if settings.transition_to_main_product %}
    data-view-transition-to-main-product
  {% endif %}
  data-image-ratio="{{ block_settings.image_ratio }}"
  {{ block.shopify_attributes }}
>
  {%- if product.media.size > 0 -%}
    {% liquid
      # Check if there are generic media that are not variant images
      assign variant_images = product.images | where: 'attached_to_variant?', true | map: 'src'
      assign generic_media_size = product.media.size | minus: variant_images.size

      # Sort media so product.featured_media.preview_image comes first as that is the most relevant image to display
      # product.featured_media updates based on search context and filters applied

      assign other_media = product.media | reject: 'src', product.featured_media
      assign media_list_to_show = product.featured_media | concat: other_media

      if product.media.size > 2 and generic_media_size > 0
        assign show_arrows = true
      endif

      # Don't overfetch media if we don't need to
      assign max_visible_slide_count = 1
      if settings.product_card_carousel
        assign max_visible_slide_count = 5
      elsif settings.show_second_image_on_hover
        assign max_visible_slide_count = 2
      endif

      capture slides
        for media in media_list_to_show
          assign loading = 'lazy'
          assign sizes = 'auto, ' | append: image_sizes

          assign hidden = false
          assign attributes = ''
          if variant_images contains media.src
            assign attributes = 'variant-image'

            if forloop.first == false
              # hide all variant images that aren't the first one
              assign hidden = true
            endif
          endif

          # Performance improvement: don't render more than 5 visible images into the slideshow
          # We'll keep the images that we need for the variant images and hover next.
          if forloop.first
            assign visible_slide_count = 0
          endif
          unless hidden
            assign visible_slide_count = visible_slide_count | plus: 1
          endunless
          if hidden == false and visible_slide_count > max_visible_slide_count
            continue
          endif

          if forloop.first and section.index == null or section.index < 5
            assign loading = 'eager'
            assign sizes = image_sizes
          endif

          assign class = 'product-media-container media-fit product-media-container--[media_type]' | replace: '[media_type]', media.media_type
          if constrain_to_viewport
            assign class = class | append: ' constrain-height'
          endif

          capture slideshow_children
            render 'product-media', media: media, sizes: sizes, loading: loading, preview_image_only: true
          endcapture

          render 'slideshow-slide', slide_id: media.id, index: forloop.index0, hidden: hidden, class: class, attributes: attributes, children: slideshow_children, media_fit: media_fit
        endfor
      endcapture

      assign slideshow_attributes = 'data-generic-media-size="[generic_media_size]"' | replace: '[generic_media_size]', generic_media_size
      if settings.product_card_carousel == false
        assign slideshow_attributes = slideshow_attributes | append: ' disabled="true"'
      endif
    %}
    <a
      class="contents"
      ref="cardGalleryLink"
      href="{{ product.selected_or_first_available_variant.url }}"
      aria-label="{{- product.title -}}"
    >
      {% render 'slideshow',
        ref: 'slideshow',
        initial_slide: 0,
        slides: slides,
        slide_count: media_list_to_show.size,
        show_arrows: show_arrows,
        attributes: slideshow_attributes
      %}
    </a>
  {% elsif product != blank and product.media.size == 0 %}
    <product-title class="product-card-gallery__title-placeholder">
      <a
        class="contents"
        ref="productTitleLink"
        href="{{ product.selected_or_first_available_variant.url }}"
        aria-hidden="true"
      >
        <span class="title-text">{{- product.title -}}</span>
      </a>
    </product-title>
  {% elsif product == blank %}
    {% liquid
      capture placeholder_image
        # Extract index from block ID (e.g., "product-card-3" -> "3")
        assign block_parts = block.id | split: '-'
        assign placeholder_index = block_parts.last | default: 0
        assign variant = placeholder_index | modulo: 3 | plus: 1
        assign placeholder_name = 'product-apparel-' | append: variant
        echo placeholder_name | placeholder_svg_tag
      endcapture
      capture placeholder_slide
        render 'slideshow-slide', index: 1, children: placeholder_image, class: 'product-media-container card-gallery__placeholder'
      endcapture
      render 'slideshow', ref: 'slideshow', slides: placeholder_slide, slide_count: 1, attributes: 'disabled="true"'
    %}
  {%- endif -%}
  {{ children }}
</div>

{% stylesheet %}
  .card-gallery {
    overflow: hidden;
    container-type: inline-size; /* Make card-gallery a container */
    container-name: card-gallery-container; /* Optional: name the container */
  }

  .card-gallery__placeholder svg {
    height: 100%;
    width: 100%;
  }

  .card-gallery svg {
    aspect-ratio: var(--gallery-aspect-ratio, var(--ratio));
  }

  .product-card-gallery__title-placeholder {
    padding: var(--padding-md);
    font-size: var(--font-size--2xl);
    line-height: var(--line-height--display-loose);
    word-break: break-word;
    color: var(--color-foreground);
    background-color: rgb(var(--color-foreground-rgb) / var(--opacity-5));
    aspect-ratio: var(--gallery-aspect-ratio);
    border-radius: var(--product-corner-radius);
    display: -webkit-box;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .product-card-gallery__title-placeholder a {
    color: var(--color-foreground);
  }

  @media screen and (min-width: 750px) {
    .product-grid[data-product-card-size='extra-large'] .product-card-gallery__title-placeholder {
      padding: var(--padding-3xl);
      font-size: var(--font-size--3xl);
    }

    .product-grid[data-product-card-size='large'] .product-card-gallery__title-placeholder {
      padding: var(--padding-2xl);
      font-size: var(--font-size--2xl);
    }

    .product-grid[data-product-card-size='medium'] .product-card-gallery__title-placeholder {
      padding: var(--padding-xl);
      font-size: var(--font-size--xl);
    }

    .product-grid[data-product-card-size='small'] .product-card-gallery__title-placeholder {
      padding: var(--padding-sm);
      font-size: var(--font-size--lg);
    }

    .product-grid[data-product-card-size='extra-large']
      .card-gallery.card-gallery--badge-top-right
      .product-card-gallery__title-placeholder {
      padding-right: calc(var(--padding-3xl) + 50px);
    }

    .product-grid[data-product-card-size='large']
      .card-gallery.card-gallery--badge-top-right
      .product-card-gallery__title-placeholder {
      padding-right: calc(var(--padding-2xl) + 50px);
    }

    .product-grid[data-product-card-size='medium']
      .card-gallery.card-gallery--badge-top-right
      .product-card-gallery__title-placeholder {
      padding-right: calc(var(--padding-xl) + 50px);
    }

    .product-grid[data-product-card-size='small']
      .card-gallery.card-gallery--badge-top-right
      .product-card-gallery__title-placeholder {
      padding-right: calc(var(--padding-sm) + 50px);
    }

    .product-grid[data-product-card-size='extra-large']
      .card-gallery.card-gallery--badge-top-left
      .product-card-gallery__title-placeholder {
      padding-top: calc(var(--padding-3xl) + 40px);
    }

    .product-grid[data-product-card-size='large']
      .card-gallery.card-gallery--badge-top-left
      .product-card-gallery__title-placeholder {
      padding-top: calc(var(--padding-2xl) + 40px);
    }

    .product-grid[data-product-card-size='medium']
      .card-gallery.card-gallery--badge-top-left
      .product-card-gallery__title-placeholder {
      padding-top: calc(var(--padding-xl) + 40px);
    }

    .product-grid[data-product-card-size='small']
      .card-gallery.card-gallery--badge-top-left
      .product-card-gallery__title-placeholder {
      padding-top: calc(var(--padding-sm) + 40px);
    }

    .product-grid[data-product-card-size='extra-large']
      .card-gallery.card-gallery--badge-bottom-left
      .product-card-gallery__title-placeholder {
      padding-bottom: calc(var(--padding-3xl) + 40px);
    }

    .product-grid[data-product-card-size='large']
      .card-gallery.card-gallery--badge-bottom-left
      .product-card-gallery__title-placeholder {
      padding-bottom: calc(var(--padding-2xl) + 40px);
    }

    .product-grid[data-product-card-size='medium']
      .card-gallery.card-gallery--badge-bottom-left
      .product-card-gallery__title-placeholder {
      padding-bottom: calc(var(--padding-xl) + 40px);
    }

    .product-grid[data-product-card-size='small']
      .card-gallery.card-gallery--badge-bottom-left
      .product-card-gallery__title-placeholder {
      padding-bottom: calc(var(--padding-sm) + 40px);
    }
  }

  @media screen and (max-width: 749px) {
    .product-card-gallery__title-placeholder {
      font-size: var(--font-size--xl);
      padding: var(--padding-md);
    }

    .product-grid[data-product-card-size]
      .card-gallery.card-gallery--badge-top-right
      .product-card-gallery__title-placeholder {
      padding-right: calc(var(--padding-sm) + 50px);
    }

    .product-grid[data-product-card-size]
      .card-gallery.card-gallery--badge-top-left
      .product-card-gallery__title-placeholder {
      padding-top: calc(var(--padding-sm) + 40px);
    }

    .product-grid[data-product-card-size]
      .card-gallery.card-gallery--badge-bottom-left
      .product-card-gallery__title-placeholder {
      padding-bottom: calc(var(--padding-sm) + 40px);
    }
  }

  [product-grid-view='zoom-out'] .card-gallery .product-card-gallery__title-placeholder {
    /* stylelint-disable-next-line declaration-no-important */
    padding: var(--padding-xs) !important;
    font-size: var(--font-size--xs);
  }

  [product-grid-view='zoom-out'] .card-gallery .slideshow-control {
    min-width: auto;
  }

  ul[product-grid-view='zoom-out'] .product-grid__card .card-gallery {
    display: block;
  }

  [product-grid-view='zoom-out']
    .card-gallery
    > :is(quick-add-component, .product-badges, slideshow-component > slideshow-controls) {
    display: none;
  }

  ul[product-grid-view='zoom-out'] .card-gallery > img {
    display: block;
  }

  .card-gallery slideshow-arrows .slideshow-control {
    /* Align icons with quick-add button */
    padding-inline: var(--padding-xl);

    @container (max-width: 249px) {
      padding-inline: 0 var(--padding-sm);
    }
  }

  /*
   * Card galleries preview the next or previous images on 'pointerenter', so we
   * try to kick load them beforehand (they are lazy loaded otherwise).
   */
  .card-gallery
    :is(
      slideshow-slide:has(+ slideshow-slide[aria-hidden='false']),
      slideshow-slide[aria-hidden='false'] + slideshow-slide
    ) {
    content-visibility: auto;

    slideshow-component[actioned] & {
      content-visibility: visible;
    }
  }
{% endstylesheet %}
