defmodule AprsmeWeb.MapLive.HistoricalLoaderTest do
  # Shares Mox stubs with other tests via the app-level :packets_module env.
  # Mox.set_mox_from_context + allow() doesn't cleanly scope inside async tests
  # without a Mox.Test start, so we pin to async: false.
  use ExUnit.Case, async: false

  import Mox

  alias AprsmeWeb.MapLive.HistoricalLoader
  alias Ecto.Adapters.SQL.Sandbox
  alias Phoenix.LiveView.Socket

  setup :verify_on_exit!
  setup :set_mox_from_context

  defp build_socket(assigns) do
    defaults = %{
      map_bounds: nil,
      map_zoom: 10,
      visible_packets: %{},
      historical_packets: %{},
      loading_generation: 0,
      pending_batch_tasks: [],
      pending_bounds: nil,
      tracked_callsign: "",
      historical_hours: "1",
      historical_loading: false,
      loading_batch: 0,
      total_batches: 1,
      historical_cursor: nil,
      __changed__: %{}
    }

    %Socket{assigns: Map.merge(defaults, assigns)}
  end

  describe "real Packets module path with seeded packets covers maybe_include_latest_packet" do
    setup do
      original = Application.get_env(:aprsme, :packets_module)
      Application.put_env(:aprsme, :packets_module, Aprsme.Packets)
      Sandbox.checkout(Aprsme.Repo)
      Sandbox.mode(Aprsme.Repo, {:shared, self()})

      on_exit(fn ->
        Application.put_env(:aprsme, :packets_module, original)
      end)

      :ok
    end

    test "non-empty tracked callsign with seeded packet exercises latest-packet inclusion" do
      Aprsme.PacketsFixtures.packet_fixture(%{
        sender: "TEST-CS",
        base_callsign: "TEST",
        ssid: "CS",
        received_at: DateTime.utc_now(),
        lat: Decimal.new("33.5"),
        lon: Decimal.new("-96.5"),
        has_position: true
      })

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          historical_loading: true,
          loading_generation: 1,
          tracked_callsign: "TEST-CS"
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, 1)
      %{assigns: assigns} = result
      assert assigns.loading_batch == 1
    end

    test "non-empty tracked callsign with non-zero batch_offset hits the fallthrough" do
      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          historical_loading: true,
          loading_generation: 1,
          tracked_callsign: "TRACK-N"
        })

      # batch_offset != 0 means maybe_include_latest_packet hits the catch-all
      # at line 309 (returns recent_packets unchanged).
      result = HistoricalLoader.load_historical_batch(socket, 1, 1)
      %{assigns: assigns} = result
      refute assigns.historical_loading
    end
  end

  describe "real Packets module path (no mock)" do
    setup do
      original = Application.get_env(:aprsme, :packets_module)
      Application.put_env(:aprsme, :packets_module, Aprsme.Packets)
      # Set up DB sandbox so DB queries actually run against the test repo.
      Sandbox.checkout(Aprsme.Repo)
      Sandbox.mode(Aprsme.Repo, {:shared, self()})
      on_exit(fn -> Application.put_env(:aprsme, :packets_module, original) end)
      :ok
    end

    test "load_historical_batch with real Packets module returns gracefully" do
      # Real Packets.get_recent_packets_for_map runs against the DB; in a clean
      # sandbox it returns []. We exercise the un-mocked branch (lines 256-309
      # in historical_loader.ex) without crashing.
      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          historical_loading: true,
          loading_generation: 1,
          tracked_callsign: ""
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, 1)
      %{assigns: assigns} = result
      refute assigns.historical_loading
    end

    test "load_historical_batch with a tracked callsign exercises maybe_include_latest_packet" do
      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          historical_loading: true,
          loading_generation: 1,
          tracked_callsign: "TRACK-1"
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, 1)
      %{assigns: assigns} = result
      refute assigns.historical_loading
    end

    test "load_historical_batch with stale generation is a no-op" do
      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          historical_loading: true,
          loading_generation: 5,
          tracked_callsign: ""
        })

      # Pass an older generation — should bail out without doing work.
      result = HistoricalLoader.load_historical_batch(socket, 0, 1)
      assert result == socket
    end
  end

  describe "cancel_pending_loads/1" do
    test "cancels pending timers and clears the list" do
      timer1 = Process.send_after(self(), :noop, 60_000)
      timer2 = Process.send_after(self(), :noop, 60_000)

      socket = build_socket(%{pending_batch_tasks: [timer1, timer2]})

      result = HistoricalLoader.cancel_pending_loads(socket)

      %{assigns: assigns} = result
      assert assigns.pending_batch_tasks == []
      # Timers should no longer be active (returns false after cancel).
      assert Process.cancel_timer(timer1) == false
      assert Process.cancel_timer(timer2) == false
    end

    test "is a no-op when no timers are pending" do
      socket = build_socket(%{pending_batch_tasks: []})
      result = HistoricalLoader.cancel_pending_loads(socket)
      %{assigns: assigns} = result
      assert assigns.pending_batch_tasks == []
    end
  end

  describe "load_historical_batch/3" do
    test "returns the socket unchanged when map_bounds is nil" do
      socket = build_socket(%{map_bounds: nil})
      result = HistoricalLoader.load_historical_batch(socket, 0, nil)
      assert result == socket
    end

    test "skips when the generation argument doesn't match loading_generation" do
      socket = build_socket(%{loading_generation: 5})
      # Stale generation — should return socket unchanged without any DB query.
      result = HistoricalLoader.load_historical_batch(socket, 0, 1)
      assert result == socket
    end
  end

  describe "start_progressive_historical_loading/1" do
    test "bumps loading_generation and schedules a failsafe" do
      socket =
        build_socket(%{
          map_bounds: nil,
          map_zoom: 5,
          loading_generation: 0
        })

      # With nil bounds, load_historical_batch returns the socket as-is, but
      # start_progressive_historical_loading should still have mutated
      # loading_batch / historical_loading / generation before calling into
      # do_load_historical_batch.
      result = HistoricalLoader.start_progressive_historical_loading(socket)
      %{assigns: assigns} = result
      assert assigns.loading_generation == 1
      assert assigns.historical_loading
      assert assigns.historical_cursor == nil
      # With map_zoom 5, progressive (non-single-batch) path is used —
      # total_batches should be a positive integer determined by the zoom.
      assert assigns.total_batches >= 2
    end

    test "uses a single batch at high zoom" do
      socket =
        build_socket(%{
          map_bounds: nil,
          map_zoom: 15,
          loading_generation: 0
        })

      result = HistoricalLoader.start_progressive_historical_loading(socket)
      %{assigns: assigns} = result
      assert assigns.total_batches == 1
      assert assigns.historical_loading
    end

    test "cancels pending timers on restart" do
      timer = Process.send_after(self(), :noop, 60_000)

      socket =
        build_socket(%{
          map_bounds: nil,
          map_zoom: 10,
          pending_batch_tasks: [timer],
          loading_generation: 3,
          historical_loading: true
        })

      result = HistoricalLoader.start_progressive_historical_loading(socket)
      %{assigns: assigns} = result
      assert assigns.loading_generation == 4
      assert assigns.pending_batch_tasks == []
      # Original timer should have been cancelled.
      assert Process.cancel_timer(timer) == false
    end
  end

  describe "load_historical_batch/3 with bounds and mocked packets" do
    test "handles an empty result set by marking loading complete" do
      # Mock returns no packets — exercises the empty-batch branch.
      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts -> [] end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          historical_loading: true,
          loading_generation: 1
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, nil)

      # Loading should be marked complete and batch advanced.
      %{assigns: assigns} = result
      refute assigns.historical_loading
      assert assigns.loading_batch == 1
    end

    test "advances loading_batch when packets come back from the mock" do
      # Return a single packet — exercises the process_loaded_packets branch.
      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts ->
        [
          %{
            id: "p-1",
            sender: "HIST-1",
            base_callsign: "HIST",
            ssid: "1",
            lat: 33.5,
            lon: -96.5,
            has_position: true,
            symbol_table_id: "/",
            symbol_code: ">",
            received_at: DateTime.utc_now(),
            path: ""
          }
        ]
      end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          historical_loading: true,
          loading_generation: 1
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, nil)

      # Either loading complete (under-full batch) or advanced a batch.
      %{assigns: assigns} = result
      assert assigns.loading_batch >= 1
    end

    test "handles empty result with pending bounds set" do
      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts -> [] end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          pending_bounds: %{north: 1.0, south: 0.0, east: 1.0, west: 0.0},
          historical_loading: true,
          loading_generation: 1
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, nil)
      %{assigns: assigns} = result
      refute assigns.historical_loading
      # process_pending_bounds is sent when loading completes with pending bounds.
      assert_received {:process_pending_bounds}
    end
  end

  describe "start_progressive_historical_loading/1 with bounds" do
    test "calls into load_historical_batch with map_zoom < 10" do
      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts -> [] end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 5,
          loading_generation: 0
        })

      result = HistoricalLoader.start_progressive_historical_loading(socket)

      %{assigns: assigns} = result
      assert assigns.loading_generation == 1
      # With empty mock results at low zoom, the first batch completes and
      # historical_loading flips back to false.
      refute assigns.historical_loading
    end
  end

  describe "advance cursor path via packets with id/received_at" do
    test "advances cursor when last packet has both id and received_at" do
      now = DateTime.utc_now()

      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts ->
        [
          %{
            id: "cursor-test-1",
            sender: "CUR1",
            base_callsign: "CUR1",
            ssid: "1",
            lat: 33.5,
            lon: -96.5,
            has_position: true,
            symbol_table_id: "/",
            symbol_code: ">",
            received_at: now,
            path: ""
          }
        ]
      end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          historical_loading: true,
          loading_generation: 1
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, nil)
      # Cursor should be set from last packet.
      %{assigns: assigns} = result
      assert assigns.historical_cursor == %{received_at: now, id: "cursor-test-1"}
    end
  end

  describe "loading with invalid-coord packets filters them out" do
    test "invalid coordinates don't break the pipeline" do
      now = DateTime.utc_now()

      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts ->
        [
          %{
            id: "bad-coord",
            sender: "BAD1",
            base_callsign: "BAD1",
            ssid: "1",
            # Out-of-range coordinates — should be filtered.
            lat: 200.0,
            lon: 500.0,
            has_position: true,
            symbol_table_id: "/",
            symbol_code: ">",
            received_at: now,
            path: ""
          }
        ]
      end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          historical_loading: true,
          loading_generation: 1
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, nil)
      # The pipeline handles the filtered packet gracefully.
      %{assigns: assigns} = result
      assert assigns.loading_generation == 1
    end
  end

  describe "zoom >= 10 single-batch branch" do
    test "starts loading in a single batch at high zoom" do
      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts -> [] end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 12,
          loading_generation: 0
        })

      result = HistoricalLoader.start_progressive_historical_loading(socket)

      # High zoom → total_batches set to 1 for single-batch path.
      %{assigns: assigns} = result
      assert assigns.total_batches == 1
      assert assigns.loading_generation == 1
    end
  end

  describe "tracking a callsign drives maybe_include_latest_packet and RF path loading" do
    test "first batch with a tracked callsign + packets triggers RF path scheduling" do
      now = DateTime.utc_now()

      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts ->
        [
          %{
            id: "rf-1",
            sender: "RFME-1",
            base_callsign: "RFME",
            ssid: "1",
            lat: 33.5,
            lon: -96.5,
            has_position: true,
            symbol_table_id: "/",
            symbol_code: ">",
            received_at: now,
            path: "K5ABC-1*,WIDE1-1"
          }
        ]
      end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          tracked_callsign: "RFME-1",
          historical_loading: true,
          loading_generation: 1
        })

      _ = HistoricalLoader.load_historical_batch(socket, 0, nil)
      # RF path scheduling sends a :load_rf_path_station_packets after 100ms.
      # Wait a bit, then check the mailbox.
      Process.sleep(120)
      assert_received {:load_rf_path_station_packets, _stations}
    end
  end

  describe "low zoom with packets path" do
    test "low zoom accumulates historical_packets without pushing markers" do
      now = DateTime.utc_now()

      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts ->
        [
          %{
            id: "lz-1",
            sender: "LZ1",
            base_callsign: "LZ",
            ssid: "1",
            lat: 33.5,
            lon: -96.5,
            has_position: true,
            symbol_table_id: "/",
            symbol_code: ">",
            received_at: now,
            path: ""
          }
        ]
      end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          # zoom <= 8 uses heat map path.
          map_zoom: 5,
          historical_loading: true,
          loading_generation: 1,
          total_batches: 3
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, nil)
      # Packet should be merged into historical_packets map.
      %{assigns: assigns} = result
      assert map_size(assigns.historical_packets) >= 1
    end
  end

  describe "advance_historical_cursor when last packet lacks id/received_at" do
    test "packet without id leaves cursor unchanged" do
      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts ->
        [
          %{
            # No :id key; advance_historical_cursor's else-branch (line 240) fires.
            sender: "NO-ID",
            base_callsign: "NOID",
            ssid: "1",
            lat: 33.0,
            lon: -96.0,
            has_position: true,
            symbol_table_id: "/",
            symbol_code: ">",
            received_at: DateTime.utc_now(),
            path: ""
          }
        ]
      end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          historical_loading: true,
          loading_generation: 1
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, nil)
      %{assigns: assigns} = result
      # Cursor not advanced since no valid id was found.
      assert assigns.historical_cursor == nil
    end
  end

  describe "get_packet_limit_for_zoom unknown zoom" do
    test "out-of-range zoom triggers @max_historical_packets default" do
      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts -> [] end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          # Zoom 25 is outside the defined ranges 0..4, 5..8, 9..11, 12..14, 15..20.
          map_zoom: 25,
          historical_loading: true,
          loading_generation: 1
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, nil)
      %{assigns: assigns} = result
      assert %{loading_generation: _} = assigns
    end
  end

  describe "low zoom heat map path with string-keyed packet ids" do
    test "string-keyed :id packet uses get_packet_key string-key clause" do
      now = DateTime.utc_now()

      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts ->
        [
          %{
            "id" => "str-keyed-1",
            "sender" => "STR-1",
            "callsign" => "STR-1",
            "received_at" => now,
            "lat" => 33.0,
            "lon" => -96.0,
            has_position: true,
            symbol_table_id: "/",
            symbol_code: ">",
            path: ""
          }
        ]
      end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 5,
          historical_loading: true,
          loading_generation: 1,
          total_batches: 3
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, nil)
      %{assigns: assigns} = result
      # The string-keyed id was placed into historical_packets via the
      # get_packet_key/1 string-key clause.
      assert map_size(assigns.historical_packets) >= 1
    end
  end

  describe "very zoomed out (zoom < 5) get_loading_params_for_zoom fallback" do
    test "zoom 2 uses the catch-all params {50, 5}" do
      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts -> [] end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 2,
          loading_generation: 0
        })

      result = HistoricalLoader.start_progressive_historical_loading(socket)
      %{assigns: assigns} = result
      # Catch-all clause produces 5 batches.
      assert assigns.total_batches == 5
    end
  end

  describe "apply_memory_limit pruning path" do
    test "exceeds @max_historical_packets and triggers prune_oldest_packets" do
      now = DateTime.utc_now()
      # Pre-populate historical_packets with > 5000 entries (the cap).
      historical_packets =
        for i <- 1..5_001, into: %{} do
          {to_string(i),
           %{
             id: "old-#{i}",
             received_at: DateTime.add(now, -i, :second),
             lat: 33.0,
             lon: -96.0
           }}
        end

      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts ->
        [
          %{
            id: "newcomer",
            sender: "NEW-1",
            base_callsign: "NEW",
            ssid: "1",
            lat: 33.5,
            lon: -96.5,
            has_position: true,
            symbol_table_id: "/",
            symbol_code: ">",
            received_at: now,
            path: ""
          }
        ]
      end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 5,
          historical_loading: true,
          historical_packets: historical_packets,
          loading_generation: 1,
          total_batches: 3
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, nil)
      %{assigns: assigns} = result
      # After pruning, the historical_packets size should be <= 5000.
      assert map_size(assigns.historical_packets) <= 5_000
    end
  end

  describe "low zoom non-final batch returns socket without heat map" do
    test "saturated low-zoom batch at offset 0 hits the non-final branch (line 368)" do
      now = DateTime.utc_now()
      # zoom 5 → batch_size 75. Return >= 75 packets so has_more = true.
      packets =
        for i <- 1..80 do
          %{
            id: "lz-final-#{i}",
            sender: "LZF-#{i}",
            base_callsign: "LZF",
            ssid: "1",
            lat: 33.0 + i * 0.001,
            lon: -96.0 + i * 0.001,
            has_position: true,
            symbol_table_id: "/",
            symbol_code: ">",
            received_at: DateTime.add(now, -i, :second),
            path: ""
          }
        end

      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts -> packets end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 5,
          historical_loading: true,
          loading_generation: 1,
          total_batches: 5
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, nil)
      %{assigns: assigns} = result
      # Saturated + total_batches >= 5 → non-final → handle_zoom_based_display
      # with is_final_batch=false hits the else-branch returning socket.
      assert %{loading_generation: _} = assigns
    end
  end

  describe "finish_historical_loading with pending_bounds set" do
    test "sends :process_pending_bounds when pending_bounds is non-nil" do
      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          historical_loading: true,
          loading_generation: 1,
          total_batches: 4,
          pending_bounds: %{north: 1.0, south: 0.0, east: 1.0, west: 0.0}
        })

      # batch_offset 3 with limit-1500 (zoom 10) and batch_size 500 →
      # packets_so_far = 3 * 500 = 1500 ≥ max → finish_historical_loading.
      result = HistoricalLoader.load_historical_batch(socket, 3, nil)
      %{assigns: assigns} = result
      refute assigns.historical_loading
      # process_pending_bounds was sent.
      assert_received {:process_pending_bounds}
    end
  end

  describe "schedules next batch when not final" do
    test "saturated batch with more rows triggers maybe_schedule_next_batch" do
      now = DateTime.utc_now()

      # Return a saturated batch so has_more = true and is_final_batch = false.
      # Default batch_size for zoom 10 is 500 — return a list of that size.
      packets =
        for i <- 1..500 do
          %{
            id: "saturate-#{i}",
            sender: "SAT-#{i}",
            base_callsign: "SAT",
            ssid: "1",
            lat: 33.5 + i * 0.0001,
            lon: -96.5 + i * 0.0001,
            has_position: true,
            symbol_table_id: "/",
            symbol_code: ">",
            received_at: DateTime.add(now, -i, :second),
            path: ""
          }
        end

      Mox.stub(Aprsme.PacketsMock, :get_recent_packets, fn _opts -> packets end)

      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          historical_loading: true,
          loading_generation: 1,
          # 4 batches expected, this is batch 0 — so not final
          total_batches: 4
        })

      result = HistoricalLoader.load_historical_batch(socket, 0, nil)
      %{assigns: assigns} = result

      # maybe_schedule_next_batch should have queued a timer.
      assert is_list(assigns.pending_batch_tasks) and assigns.pending_batch_tasks != []
    end
  end

  describe "max packets-for-zoom limit" do
    test "finishes loading when batch_offset * batch_size exceeds zoom limit" do
      # At zoom 10, limit=1500, batch_size=500. A batch_offset of 3 exceeds
      # the 1500-row zoom limit, so the load should finish without a query.
      socket =
        build_socket(%{
          map_bounds: %{north: 34.0, south: 32.0, east: -95.0, west: -97.0},
          map_zoom: 10,
          historical_loading: true,
          total_batches: 4,
          loading_generation: 1
        })

      result = HistoricalLoader.load_historical_batch(socket, 3, nil)
      %{assigns: assigns} = result
      # finish_historical_loading flips historical_loading off.
      refute assigns.historical_loading
    end
  end
end
