

{% stylesheet %}
  .rating-wrapper {
    width: 100%;
    gap: var(--gap-xs);
    flex-wrap: wrap;
  }

  .rating-color--primary {
    --star-fill-color: var(--color-primary);
  }

  .rating-color--foreground {
    --star-fill-color: var(--color-foreground);
  }

  .rating-wrapper,
  .rating {
    display: flex;
    align-items: center;
  }

  .rating-wrapper.justify-right {
    flex-direction: row-reverse;
  }

  .rating {
    gap: var(--gap-3xs);
  }

  .rating-wrapper .rating-text,
  .rating-wrapper .rating-count,
  .rating-wrapper .rating-count-separator {
    color: var(--star-fill-color);
    margin: 0;
    white-space: nowrap;
  }

  .rating-count-separator {
    opacity: 0.2;
    padding-left: calc(var(--padding-xs) / 2);
    padding-right: var(--padding-xs);
  }

  .stars {
    height: var(--star-size);
    fill: var(--empty-star-fill-color);
  }

  .filled-star {
    fill: var(--star-fill-color);
  }
{% endstylesheet %}

{% liquid
  assign product = block.settings.product
  assign rating = product.metafields.reviews.rating.value.rating
  assign scale_max = product.metafields.reviews.rating.value.scale_max
  assign rating_count = product.metafields.reviews.rating_count

  if request.visual_preview_mode and product == blank
    assign product = collections.all.products.first
    assign rating = product.metafields.reviews.rating.value | default: 4
    assign scale_max = product.metafields.reviews.rating.value.scale_max | default: 5
    assign rating_count = product.metafields.reviews.rating_count | default: 3
  endif
-%}

{%- if rating != blank -%}
  {% liquid
    assign star_count_rating = scale_max
    assign decimal_rating = 0
    assign decimal = rating | modulo: 1

    if decimal >= 0.3 and decimal <= 0.7
      assign decimal_rating = 0.5
    elsif decimal > 0.7
      assign decimal_rating = 1
    endif

    # this is used so I can tell how many stars I need to fill. When the decimal rating above is 0.5 or 1 I count it as one as the half star is dealt with with a SVG linear gradient.
    assign decimal_rounded = decimal_rating | ceil

    assign svg_filled_stars = rating | floor | plus: decimal_rounded
  %}

  <div
    class="rating-wrapper justify-{{ block.settings.alignment }} rating-color--{{ block.settings.rating_color }}"
    {{ block.shopify_attributes }}
  >
    <svg
      class="visually-hidden"
      style="width: 0; height: 0;"
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 32 32"
    >
      <defs>
        <linearGradient id="half" x1="0" x2="100%" y1="0" y2="0">
          <stop offset="50%" stop-color="var(--star-fill-color)"></stop>
          <stop offset="50%" stop-color="{% if block.settings.stars_style == "outline" %}transparent{% else %}rgb(from var(--star-fill-color) r g b/ 0.2){% endif %}"></stop>
        </linearGradient>

        <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" id="star">
          <path d="M31.547 12a.848.848 0 00-.677-.577l-9.427-1.376-4.224-8.532a.847.847 0 00-1.516 0l-4.218 8.534-9.427 1.355a.847.847 0 00-.467 1.467l6.823 6.664-1.612 9.375a.847.847 0 001.23.893l8.428-4.434 8.432 4.432a.847.847 0 001.229-.894l-1.615-9.373 6.822-6.665a.845.845 0 00.214-.869z" />
        </symbol>
      </defs>
    </svg>
    <div
      class="rating"
      style="--star-size: calc(var(--font-{{ block.settings.type_preset }}--size) * 1.1);"
      aria-label="Rating of this product is {{ rating }} out of 5"
    >
      {% if block.settings.stars_style == 'single' %}
        <svg
          class="stars {% if svg_filled_stars > 0 %}filled-star{% endif %}"
          viewBox="0 0 32 32"
          style="--empty-star-fill-color:rgb(from var(--star-fill-color) r g b/ 0.2)"
        >
          <use xlink:href="#star"></use>
        </svg>
      {% else %}
        {%- for star in (1..star_count_rating) -%}
          <svg
            class="stars {% if star <= svg_filled_stars %}filled-star{% endif %}"
            viewBox="0 0 32 32"
            style="--empty-star-fill-color:{% if block.settings.stars_style == 'outline' %}transparent{% else %}rgb(from var(--star-fill-color) r g b/ 0.2){% endif %}"
          >
            <use xlink:href="#star"{% if decimal_rating == 0.5 and star == svg_filled_stars %} fill="url(#half)"{% endif %}></use>
            {% if block.settings.stars_style == "outline" %}
              <use xlink:href="#star" fill="none" stroke="var(--star-fill-color)" stroke-width="var(--icon-stroke-width)"></use>
            {% endif %}
          </svg>
        {%- endfor -%}
      {% endif %}
    </div>

    {%- if block.settings.show_number or block.settings.stars_style == 'single' -%}
      <p class="rating-count {{ block.settings.type_preset }}">
        {%- if block.settings.stars_style == 'single' -%}
          {{- rating | round: 1 }}
        {%- endif -%}
        {%- if block.settings.stars_style == 'single' and block.settings.show_number -%}
          <span class="rating-count-separator">|</span>
        {%- endif -%}
        {%- if block.settings.show_number -%}
          {{- rating_count }}
          {{ 'content.reviews' | t }}
        {%- endif -%}
      </p>
    {%- endif -%}
  </div>
{%- endif -%}

{% schema %}
{
  "name": "t:names.product_review_stars",
  "tag": null,
  "settings": [
    {
      "type": "product",
      "id": "product",
      "label": "t:settings.product"
    },
    {
      "type": "select",
      "id": "stars_style",
      "label": "t:settings.style",
      "options": [
        {
          "value": "outline",
          "label": "t:options.outline"
        },
        {
          "value": "shaded",
          "label": "t:options.shaded"
        },
        {
          "value": "single",
          "label": "t:options.single"
        }
      ],
      "default": "shaded"
    },
    {
      "type": "checkbox",
      "id": "show_number",
      "label": "t:settings.review_count",
      "default": true
    },
    {
      "type": "select",
      "id": "rating_color",
      "label": "t:settings.color",
      "options": [
        {
          "value": "foreground",
          "label": "t:options.text"
        },
        {
          "value": "primary",
          "label": "t:options.body"
        }
      ],
      "default": "primary"
    },
    {
      "type": "header",
      "content": "t:content.typography"
    },
    {
      "type": "select",
      "id": "type_preset",
      "label": "t:settings.preset",
      "options": [
        {
          "value": "paragraph",
          "label": "t:options.paragraph"
        },
        {
          "value": "h1",
          "label": "t:options.h1"
        },
        {
          "value": "h2",
          "label": "t:options.h2"
        },
        {
          "value": "h3",
          "label": "t:options.h3"
        },
        {
          "value": "h4",
          "label": "t:options.h4"
        },
        {
          "value": "h5",
          "label": "t:options.h5"
        },
        {
          "value": "h6",
          "label": "t:options.h6"
        }
      ],
      "default": "paragraph"
    },
    {
      "type": "text_alignment",
      "id": "alignment",
      "label": "t:settings.alignment",
      "default": "left"
    }
  ],
  "presets": [
    {
      "name": "t:names.product_review_stars",
      "category": "t:categories.product",
      "settings": {
        "product": "{{ closest.product }}"
      }
    }
  ]
}
{% endschema %}
