defmodule BerrypodWeb.Admin.MediaTest do
  use BerrypodWeb.ConnCase, async: false

  import Phoenix.LiveViewTest
  import Berrypod.AccountsFixtures

  alias Berrypod.Media

  @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>"
  }

  @raster_attrs %{
    image_type: "media",
    filename: "banner.png",
    content_type: "image/png",
    file_size: 1024,
    data: <<137, 80, 78, 71>>,
    alt: "A banner image"
  }

  setup do
    user = user_fixture()
    %{user: user}
  end

  describe "media library page" do
    setup %{conn: conn, user: user} do
      %{conn: log_in_user(conn, user)}
    end

    test "renders media library for admin", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/media")
      assert html =~ "Media"
      assert html =~ "Upload image"
    end

    test "shows images in grid", %{conn: conn} do
      {:ok, _} = Media.upload_image(@svg_attrs)
      {:ok, _} = Media.upload_image(@raster_attrs)

      {:ok, _view, html} = live(conn, ~p"/admin/media")
      assert html =~ "logo.svg"
      assert html =~ "banner.png"
    end

    test "filters by type", %{conn: conn} do
      {:ok, _} = Media.upload_image(@svg_attrs)
      {:ok, _} = Media.upload_image(@raster_attrs)

      {:ok, view, _html} = live(conn, ~p"/admin/media")

      html = render_change(view, "filter_type", %{"type" => "media"})
      assert html =~ "banner.png"
      refute html =~ "logo.svg"
    end

    test "filters by search", %{conn: conn} do
      {:ok, _} = Media.upload_image(@svg_attrs)
      {:ok, _} = Media.upload_image(@raster_attrs)

      {:ok, view, _html} = live(conn, ~p"/admin/media")

      html = render_keyup(view, "filter_search", %{"value" => "banner"})
      assert html =~ "banner.png"
      refute html =~ "logo.svg"
    end

    test "selects image and shows detail panel", %{conn: conn} do
      {:ok, image} = Media.upload_image(@raster_attrs)

      {:ok, view, _html} = live(conn, ~p"/admin/media")

      html = render_click(view, "select_image", %{"id" => image.id})
      assert html =~ "Image details"
      assert html =~ "banner.png"
      assert html =~ "Alt text"
    end

    test "updates metadata", %{conn: conn} do
      {:ok, image} = Media.upload_image(@raster_attrs)

      {:ok, view, _html} = live(conn, ~p"/admin/media")
      render_click(view, "select_image", %{"id" => image.id})

      render_submit(view, "update_metadata", %{
        "metadata" => %{"alt" => "Updated alt", "caption" => "New caption", "tags" => "hero"}
      })

      updated = Media.get_image(image.id)
      assert updated.alt == "Updated alt"
      assert updated.caption == "New caption"
      assert updated.tags == "hero"
    end

    test "deletes orphaned image", %{conn: conn} do
      {:ok, image} = Media.upload_image(@raster_attrs)

      {:ok, view, _html} = live(conn, ~p"/admin/media")
      render_click(view, "select_image", %{"id" => image.id})
      render_click(view, "confirm_delete")

      html = render_click(view, "delete_image")
      assert html =~ "Image deleted"
      assert Media.get_image(image.id) == nil
    end

    test "refuses to delete in-use image", %{conn: conn} do
      {:ok, image} = Media.upload_image(@svg_attrs)
      Berrypod.Settings.update_theme_settings(%{logo_image_id: image.id})

      {:ok, view, _html} = live(conn, ~p"/admin/media")
      render_click(view, "select_image", %{"id" => image.id})
      render_click(view, "confirm_delete")

      html = render_click(view, "delete_image")
      assert html =~ "Cannot delete"
      assert Media.get_image(image.id) != nil
    end

    test "orphan filter shows only unreferenced images", %{conn: conn} do
      {:ok, logo} = Media.upload_image(@svg_attrs)
      {:ok, _orphan} = Media.upload_image(@raster_attrs)
      Berrypod.Settings.update_theme_settings(%{logo_image_id: logo.id})

      {:ok, view, _html} = live(conn, ~p"/admin/media")

      html = render_click(view, "toggle_orphans")
      assert html =~ "banner.png"
      refute html =~ "logo.svg"
    end

    test "shows usage info for referenced image", %{conn: conn} do
      {:ok, image} = Media.upload_image(@svg_attrs)
      Berrypod.Settings.update_theme_settings(%{logo_image_id: image.id})

      {:ok, view, _html} = live(conn, ~p"/admin/media")
      html = render_click(view, "select_image", %{"id" => image.id})
      assert html =~ "Used in"
      assert html =~ "Logo"
    end

    test "shows no-alt-text warning for images without alt", %{conn: conn} do
      {:ok, _} = Media.upload_image(Map.delete(@raster_attrs, :alt))

      {:ok, _view, html} = live(conn, ~p"/admin/media")
      assert html =~ "No alt text"
    end
  end
end
