defmodule SimpleshopTheme.MediaTest do
  use SimpleshopTheme.DataCase, async: true

  alias SimpleshopTheme.Media

  @valid_attrs %{
    image_type: "logo",
    filename: "logo.png",
    content_type: "image/png",
    file_size: 1024,
    data: <<137, 80, 78, 71>>
  }

  @svg_attrs %{
    image_type: "logo",
    filename: "logo.svg",
    content_type: "image/svg+xml",
    file_size: 512,
    data: "<svg xmlns=\"http://www.w3.org/2000/svg\"><circle r=\"10\"/></svg>"
  }

  describe "upload_image/1" do
    test "uploads an image with valid attributes" do
      assert {:ok, image} = Media.upload_image(@valid_attrs)
      assert image.image_type == "logo"
      assert image.filename == "logo.png"
      assert image.content_type == "image/png"
      assert image.is_svg == false
    end

    test "detects and stores SVG content" do
      assert {:ok, image} = Media.upload_image(@svg_attrs)
      assert image.is_svg == true
      assert image.svg_content == @svg_attrs.data
    end

    test "validates required fields" do
      assert {:error, changeset} = Media.upload_image(%{})
      assert "can't be blank" in errors_on(changeset).image_type
      assert "can't be blank" in errors_on(changeset).filename
    end

    test "validates image_type inclusion" do
      attrs = Map.put(@valid_attrs, :image_type, "invalid")
      assert {:error, changeset} = Media.upload_image(attrs)
      assert "is invalid" in errors_on(changeset).image_type
    end

    test "validates file size" do
      attrs = Map.put(@valid_attrs, :file_size, 10_000_000)
      assert {:error, changeset} = Media.upload_image(attrs)
      assert "must be less than 5000000" in errors_on(changeset).file_size
    end
  end

  describe "get_image/1" do
    test "returns image by id" do
      {:ok, image} = Media.upload_image(@valid_attrs)
      assert ^image = Media.get_image(image.id)
    end

    test "returns nil for nonexistent id" do
      assert Media.get_image(Ecto.UUID.generate()) == nil
    end
  end

  describe "get_logo/0 and get_header/0" do
    test "get_logo returns a logo" do
      {:ok, logo} = Media.upload_image(@valid_attrs)

      result = Media.get_logo()
      assert result.id == logo.id
      assert result.image_type == "logo"
    end

    test "get_header returns most recent header" do
      attrs = Map.put(@valid_attrs, :image_type, "header")
      {:ok, header} = Media.upload_image(attrs)

      result = Media.get_header()
      assert result.id == header.id
    end

    test "get_logo returns nil when no logos exist" do
      assert Media.get_logo() == nil
    end
  end

  describe "delete_image/1" do
    test "deletes an image" do
      {:ok, image} = Media.upload_image(@valid_attrs)
      assert {:ok, _} = Media.delete_image(image)
      assert Media.get_image(image.id) == nil
    end
  end

  describe "list_images_by_type/1" do
    test "lists all images of a specific type" do
      {:ok, logo1} = Media.upload_image(@valid_attrs)
      {:ok, logo2} = Media.upload_image(@valid_attrs)
      {:ok, _header} = Media.upload_image(Map.put(@valid_attrs, :image_type, "header"))

      logos = Media.list_images_by_type("logo")
      assert length(logos) == 2
      assert Enum.any?(logos, &(&1.id == logo1.id))
      assert Enum.any?(logos, &(&1.id == logo2.id))
    end

    test "returns empty list when no images of type exist" do
      assert Media.list_images_by_type("product") == []
    end
  end
end
