defmodule Berrypod.Products.ProductImageTest do
  use Berrypod.DataCase, async: false

  alias Berrypod.Products.ProductImage

  import Berrypod.ProductsFixtures

  describe "changeset/2" do
    setup do
      product = product_fixture()
      {:ok, product: product}
    end

    test "valid attributes create a valid changeset", %{product: product} do
      attrs = valid_product_image_attrs(%{product_id: product.id})
      changeset = ProductImage.changeset(%ProductImage{}, attrs)

      assert changeset.valid?
    end

    test "requires product_id", %{product: _product} do
      attrs = valid_product_image_attrs() |> Map.delete(:product_id)
      changeset = ProductImage.changeset(%ProductImage{}, attrs)

      refute changeset.valid?
      assert "can't be blank" in errors_on(changeset).product_id
    end

    test "requires src", %{product: product} do
      attrs =
        valid_product_image_attrs(%{product_id: product.id})
        |> Map.delete(:src)

      changeset = ProductImage.changeset(%ProductImage{}, attrs)

      refute changeset.valid?
      assert "can't be blank" in errors_on(changeset).src
    end

    test "defaults position to 0", %{product: product} do
      attrs =
        valid_product_image_attrs(%{product_id: product.id})
        |> Map.delete(:position)

      changeset = ProductImage.changeset(%ProductImage{}, attrs)

      assert changeset.valid?
    end

    test "accepts optional alt text", %{product: product} do
      attrs = valid_product_image_attrs(%{product_id: product.id, alt: "Product image alt text"})
      changeset = ProductImage.changeset(%ProductImage{}, attrs)

      assert changeset.valid?
      assert changeset.changes.alt == "Product image alt text"
    end

    test "allows nil alt text", %{product: product} do
      attrs = valid_product_image_attrs(%{product_id: product.id, alt: nil})
      changeset = ProductImage.changeset(%ProductImage{}, attrs)

      assert changeset.valid?
    end
  end

  # =============================================================================
  # Display helpers
  # =============================================================================

  describe "url/2" do
    test "prefers local image_id over src" do
      image = %{image_id: "abc-123", src: "https://cdn.example.com/img.jpg"}
      assert ProductImage.url(image) == "/image_cache/abc-123-800.webp"
    end

    test "accepts custom width" do
      image = %{image_id: "abc-123", src: "https://cdn.example.com/img.jpg"}
      assert ProductImage.url(image, 400) == "/image_cache/abc-123-400.webp"
    end

    test "handles mockup URLs with size suffix" do
      image = %{image_id: nil, src: "/mockups/product-1"}
      assert ProductImage.url(image, 800) == "/mockups/product-1-800.webp"
    end

    test "falls back to src when no image_id" do
      image = %{image_id: nil, src: "https://cdn.example.com/img.jpg"}
      assert ProductImage.url(image) == "https://cdn.example.com/img.jpg"
    end

    test "returns nil when neither image_id nor src" do
      assert ProductImage.url(%{image_id: nil, src: nil}) == nil
    end

    test "returns nil for nil input" do
      assert ProductImage.url(nil) == nil
    end
  end

  describe "thumbnail_url/1" do
    test "returns thumb path for local image" do
      image = %{image_id: "abc-123"}
      assert ProductImage.thumbnail_url(image) == "/image_cache/abc-123-thumb.jpg"
    end

    test "falls back to src when no image_id" do
      image = %{image_id: nil, src: "https://cdn.example.com/img.jpg"}
      assert ProductImage.thumbnail_url(image) == "https://cdn.example.com/img.jpg"
    end

    test "returns nil for nil input" do
      assert ProductImage.thumbnail_url(nil) == nil
    end
  end

  describe "source_width/1" do
    test "returns source_width from preloaded image" do
      image = %{image: %{source_width: 2400}}
      assert ProductImage.source_width(image) == 2400
    end

    test "returns nil when image not preloaded" do
      assert ProductImage.source_width(%{}) == nil
    end

    test "returns nil when source_width is nil" do
      assert ProductImage.source_width(%{image: %{source_width: nil}}) == nil
    end
  end
end
