defmodule Microwaveprop.Propagation.GridTaskEnqueuerTest do
  use Microwaveprop.DataCase, async: true

  import Ecto.Query

  alias Microwaveprop.Propagation.GridTaskEnqueuer
  alias Microwaveprop.Repo

  test "seeds one row per fh=1..18" do
    run_time = ~U[2026-04-19 15:00:00Z]
    assert {:ok, 18} = GridTaskEnqueuer.seed(run_time)

    rows =
      Repo.all(
        from(g in "grid_tasks",
          where: g.run_time == ^run_time,
          select: %{forecast_hour: g.forecast_hour, status: g.status, valid_time: g.valid_time}
        )
      )

    assert length(rows) == 18
    assert rows |> Enum.map(& &1.forecast_hour) |> Enum.sort() == Enum.to_list(1..18)
    assert Enum.all?(rows, &(&1.status == "queued"))

    # Raw schemaless selects return NaiveDateTime; compare against the
    # equivalent naive form.
    expected_naive = DateTime.to_naive(run_time)

    Enum.each(rows, fn r ->
      expected = NaiveDateTime.add(expected_naive, r.forecast_hour * 3600, :second)
      assert NaiveDateTime.compare(r.valid_time, expected) == :eq
    end)
  end

  test "is idempotent: reseeding the same run_time inserts nothing" do
    run_time = ~U[2026-04-19 16:00:00Z]
    assert {:ok, 18} = GridTaskEnqueuer.seed(run_time)
    assert {:ok, 0} = GridTaskEnqueuer.seed(run_time)

    count = Repo.one(from(g in "grid_tasks", where: g.run_time == ^run_time, select: count()))

    assert count == 18
  end

  test "never emits a row for fh=0 — Elixir keeps that chain step" do
    run_time = ~U[2026-04-19 17:00:00Z]
    assert {:ok, 18} = GridTaskEnqueuer.seed(run_time)

    f0_count = Repo.one(from(g in "grid_tasks", where: g.run_time == ^run_time and g.forecast_hour == 0, select: count()))

    assert f0_count == 0
  end
end
