defmodule MicrowavepropWeb.WeatherCaMapLiveTest do
  # async: false because we touch the shared scalar / profile dirs.
  use MicrowavepropWeb.ConnCase, async: false

  import Phoenix.LiveViewTest

  alias Microwaveprop.Propagation.ProfilesFile
  alias Microwaveprop.Weather.GridCache
  alias Microwaveprop.Weather.ScalarFile

  setup do
    GridCache.clear()

    on_exit(fn ->
      GridCache.clear()
      ProfilesFile.prune_older_than(~U[2099-12-31 23:59:59Z])
    end)

    :ok
  end

  test "mounts at /weather-ca with Canadian default viewport", %{conn: conn} do
    {:ok, _lv, html} = live(conn, ~p"/weather-ca")

    # Default viewport is centered roughly on central Canada at a low
    # zoom — different from /weather's DFW@z7. The exact numbers are
    # asserted so a routing accident (mounting WeatherMapLive at this
    # path by mistake) is caught.
    assert html =~ ~s(data-initial-lat="55.0")
    assert html =~ ~s(data-initial-lon="-100.0")
    assert html =~ ~s(data-initial-zoom="4")
  end

  test "renders the weather map element with data-source=hrdps", %{conn: conn} do
    {:ok, _lv, html} = live(conn, ~p"/weather-ca")

    # The JS hook reads data-source and appends &source=hrdps to its cell
    # fetches. Without this attribute the page would silently fall back
    # to HRRR-only reads and never show Canadian data.
    assert html =~ ~s(data-source="hrdps")
  end

  test "viewport_changed event push_patches /weather-ca, not /weather", %{conn: conn} do
    {:ok, lv, _html} = live(conn, ~p"/weather-ca")

    render_hook(lv, "viewport_changed", %{"lat" => 60.0, "lon" => -110.0, "zoom" => 5})

    assert_patch(lv, "/weather-ca?layer=temperature&lat=60.0&lon=-110.0&zoom=5")
  end

  test "select_layer push_patches a /weather-ca URL", %{conn: conn} do
    {:ok, lv, _html} = live(conn, ~p"/weather-ca")

    render_hook(lv, "select_layer", %{"layer" => "pwat"})

    assert_patch(lv, "/weather-ca?layer=pwat&lat=55.0&lon=-100.0&zoom=4")
  end

  test "shows HRDPS valid_times even when several hours old (no 1h cutoff)", %{conn: conn} do
    # HRDPS publishes 4x/day with ~3-4h latency, plus our chain step
    # takes ~13 min. The 1-hour cutoff /weather uses would routinely
    # leave /weather-ca empty between fresh chain steps. Hand-write a
    # 4-hour-old HRDPS chunk and confirm it lands in the timeline.
    now =
      DateTime.utc_now()
      |> DateTime.truncate(:second)
      |> Map.put(:minute, 0)
      |> Map.put(:second, 0)

    stale_t = DateTime.add(now, -4 * 3600, :second)
    hrdps_dir = ScalarFile.dir_for_hrdps(stale_t)
    File.mkdir_p!(hrdps_dir)

    payload =
      Msgpax.pack!(
        [%{"lat" => 53.0, "lon" => -60.0, "valid_time" => DateTime.to_iso8601(stale_t), "temperature" => 8.0}],
        iodata: false
      )

    File.write!(Path.join(hrdps_dir, "10_-12.mp.gz"), :zlib.gzip(payload))

    on_exit(fn -> File.rm_rf!(hrdps_dir) end)

    {:ok, _lv, html} = live(conn, ~p"/weather-ca")

    iso = DateTime.to_iso8601(stale_t)
    assert html =~ iso, "4-hour-old HRDPS valid_time should appear in /weather-ca timeline"
  end
end
