defmodule TarakanWeb.LeaderboardLiveTest do
  use TarakanWeb.ConnCase

  import Phoenix.LiveViewTest

  defp verified_contributor do
    submitter = github_account_fixture()
    repository = listed_github_repository_fixture(submitter)
    scan = scan_fixture(repository, submitter, %{"findings_json" => findings_json_fixture(1)})
    confirmation_fixture(scan, reviewer_account_fixture())
    confirmation_fixture(scan, reviewer_account_fixture())
    {submitter, repository}
  end

  test "renders ranked contributors linking to their profiles", %{conn: conn} do
    {submitter, _repository} = verified_contributor()

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

    assert has_element?(view, "#leaderboard-rank-1")
    assert has_element?(view, ~s(#leaderboard a[href="/#{submitter.handle}"]))
    # The distinct verified canonical finding (+30) puts the submitter on top;
    # the report occurrence itself is not a second reputation event.
    assert has_element?(view, "#leaderboard-rank-1", submitter.handle)
    assert has_element?(view, "#leaderboard-rank-1", "30")
  end

  test "the leaderboard can be re-sorted", %{conn: conn} do
    verified_contributor()
    {:ok, view, _html} = live(conn, ~p"/leaderboard")

    html = view |> element("#leaderboard-sort button[phx-value-by='findings']") |> render_click()
    assert_patch(view, ~p"/leaderboard?sort=findings")
    assert html =~ ~s(aria-pressed="true")
  end

  test "filter controls render and patching filters the entries", %{conn: conn} do
    {submitter, _repository} = verified_contributor()

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

    assert has_element?(view, "#leaderboard-severity")
    assert has_element?(view, "#leaderboard-window")
    assert has_element?(view, "#leaderboard-rank-1")

    # The fixture's findings are "high"; filtering to critical empties the board.
    view |> element("#leaderboard-severity-form") |> render_change(%{"severity" => "critical"})
    assert_patch(view, ~p"/leaderboard?severity=critical")
    assert has_element?(view, "#leaderboard-empty")
    refute has_element?(view, "#leaderboard-rank-1")

    # Clearing the severity brings the contributor back; the window tabs patch too.
    view |> element("#leaderboard-severity-form") |> render_change(%{"severity" => ""})
    assert has_element?(view, "#leaderboard-rank-1", submitter.handle)

    view |> element("#leaderboard-window button[phx-value-window='7']") |> render_click()
    assert_patch(view, ~p"/leaderboard?window=7")
    assert has_element?(view, "#leaderboard-rank-1", submitter.handle)
  end

  test "rows surface slashed stakes", %{conn: conn} do
    {submitter, repository} = verified_contributor()

    # A second report (a distinct finding) is refuted by a dispute quorum.
    refuted =
      scan_fixture(repository, submitter, %{
        "findings_json" =>
          Jason.encode!(%{
            "tarakan_scan_format" => 1,
            "findings" => [
              %{
                "file" => "lib/example/other.ex",
                "severity" => "high",
                "title" => "Refuted finding #{System.unique_integer([:positive])}",
                "description" => "Slashed stake fixture."
              }
            ]
          })
      })

    confirmation_fixture(refuted, reviewer_account_fixture(), "disputed")
    confirmation_fixture(refuted, reviewer_account_fixture(), "disputed")

    {:ok, view, _html} = live(conn, ~p"/leaderboard")
    assert has_element?(view, "#leaderboard-rank-1", "1 slashed")
  end

  test "an empty record shows the empty state", %{conn: conn} do
    {:ok, view, _html} = live(conn, ~p"/leaderboard")
    assert has_element?(view, "#leaderboard-empty")
  end

  test "rows show earned badge chips after the handle", %{conn: conn} do
    {submitter, _repository} = verified_contributor()

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

    assert has_element?(view, "#leaderboard-rank-1-badge-first_blood", "First blood")
    refute has_element?(view, "#leaderboard-rank-1-badge-century")

    # The reviewer accounts checked the report but earned no badges, so their
    # rows (if ranked) carry no chips.
    html = render(view)
    assert html =~ submitter.handle
  end

  test "the header links to the leaderboard", %{conn: conn} do
    {:ok, view, _html} = live(conn, ~p"/")
    assert has_element?(view, ~s(a[href="/leaderboard"]))
  end
end
