defmodule FirehoseWeb.SourceViewerTest do
  use FirehoseWeb.ConnCase, async: true

  import Phoenix.LiveViewTest

  alias FirehoseWeb.MicroprintsLive

  defp expand_file(view, path) do
    view
    |> element("button[phx-value-path=\"#{path}\"]", "Expand")
    |> render_click()
  end

  defp click_microprint_rect(view, path, line) do
    render_click(view, "highlight_line", %{"line" => Integer.to_string(line), "path" => path})
  end

  describe "line elements" do
    test "render with unique ids when file is expanded", %{conn: conn} do
      files = MicroprintsLive.scan_source_files()
      file = List.first(files)

      {:ok, view, _html} = live(conn, ~p"/microprints")
      expand_file(view, file)

      assert has_element?(view, "#line-1"),
             "Line 1 should exist in the source viewer"

      assert has_element?(view, "#line-2"),
             "Line 2 should exist in the source viewer"

      assert has_element?(view, "#line-3"),
             "Line 3 should exist in the source viewer"
    end
  end

  describe "highlight class" do
    test "is added to line on microprint click", %{conn: conn} do
      files = MicroprintsLive.scan_source_files()
      file = List.first(files)

      {:ok, view, _html} = live(conn, ~p"/microprints")
      expand_file(view, file)

      click_microprint_rect(view, file, 1)

      assert has_element?(view, "#line-1.sv-line-highlighted"),
             "Line 1 should have the highlighted class after click"
    end

    test "is removed on re-clicking the same line", %{conn: conn} do
      files = MicroprintsLive.scan_source_files()
      file = List.first(files)

      {:ok, view, _html} = live(conn, ~p"/microprints")
      expand_file(view, file)

      click_microprint_rect(view, file, 1)

      assert has_element?(view, "#line-1.sv-line-highlighted"),
             "Line 1 should be highlighted after first click"

      click_microprint_rect(view, file, 1)

      refute has_element?(view, "#line-1.sv-line-highlighted"),
             "Line 1 should no longer be highlighted after second click"
    end

    test "persists when expand is restored from URL params", %{conn: conn} do
      files = MicroprintsLive.scan_source_files()
      file = List.first(files)

      {:ok, view, _html} =
        live(conn, ~p"/microprints?expanded=#{file}&line=1&highlighted=#{file}")

      assert has_element?(view, "#line-1.sv-line-highlighted"),
             "Line 1 should be highlighted when restored from URL params"
    end
  end

  describe "different file highlighting" do
    test "collapses file A and removes its source viewer when highlighting file B", %{conn: conn} do
      files = MicroprintsLive.scan_source_files()
      assert length(files) >= 2, "Need at least 2 files to test different-file highlighting"

      [file_a, file_b | _] = files

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

      expand_file(view, file_a)
      click_microprint_rect(view, file_a, 1)

      assert has_element?(view, "#line-1.sv-line-highlighted"),
             "Line 1 in file A should be highlighted before switching"

      click_microprint_rect(view, file_b, 2)

      refute has_element?(view, "#line-1"),
             "File A source viewer should be gone after highlighting a different file"
    end
  end
end
