defmodule Berrypod.Workers.FaviconGeneratorWorkerTest do
  use Berrypod.DataCase, async: false

  import Berrypod.ImageFixtures

  alias Berrypod.Media
  alias Berrypod.Workers.FaviconGeneratorWorker

  describe "perform/1" do
    test "generates PNG variants from a raster image" do
      image = image_fixture(%{image_type: "icon"})

      assert :ok =
               FaviconGeneratorWorker.perform(%Oban.Job{
                 args: %{"source_image_id" => image.id}
               })

      variants = Media.get_favicon_variants()
      assert variants != nil
      assert variants.source_image_id == image.id
      assert is_binary(variants.png_32)
      assert is_binary(variants.png_180)
      assert is_binary(variants.png_192)
      assert is_binary(variants.png_512)
      assert variants.svg == nil
      assert variants.generated_at != nil
    end

    test "generates correct PNG sizes" do
      image = image_fixture(%{image_type: "icon"})

      :ok =
        FaviconGeneratorWorker.perform(%Oban.Job{
          args: %{"source_image_id" => image.id}
        })

      variants = Media.get_favicon_variants()

      # Verify PNG data starts with PNG magic bytes
      for field <- [:png_32, :png_180, :png_192, :png_512] do
        data = Map.get(variants, field)
        assert <<137, 80, 78, 71, _rest::binary>> = data, "#{field} should be valid PNG"
      end
    end

    test "stores SVG as-is for SVG source" do
      image = svg_fixture()

      :ok =
        FaviconGeneratorWorker.perform(%Oban.Job{
          args: %{"source_image_id" => image.id}
        })

      variants = Media.get_favicon_variants()
      assert variants != nil
      assert is_binary(variants.svg)
      assert variants.svg == image.svg_content
    end

    test "replaces existing variants on regeneration" do
      image = image_fixture(%{image_type: "icon"})

      :ok =
        FaviconGeneratorWorker.perform(%Oban.Job{
          args: %{"source_image_id" => image.id}
        })

      first_variants = Media.get_favicon_variants()
      first_id = first_variants.id

      # Generate again
      :ok =
        FaviconGeneratorWorker.perform(%Oban.Job{
          args: %{"source_image_id" => image.id}
        })

      second_variants = Media.get_favicon_variants()
      assert second_variants.id != first_id
    end

    test "cancels when image not found" do
      assert {:cancel, :image_not_found} =
               FaviconGeneratorWorker.perform(%Oban.Job{
                 args: %{"source_image_id" => Ecto.UUID.generate()}
               })
    end
  end
end
