defmodule Microwaveprop.Workers.SolarIndexWorkerTest do
  use Microwaveprop.DataCase, async: true

  alias Microwaveprop.Weather.SolarClient
  alias Microwaveprop.Weather.SolarIndex
  alias Microwaveprop.Workers.SolarIndexWorker

  defp gfz_body_with_recent_dates do
    today = Date.utc_today()
    yesterday = Date.add(today, -1)

    """
    # Comment line
    #{today.year} #{String.pad_leading("#{today.month}", 2, "0")} #{String.pad_leading("#{today.day}", 2, "0")} 33769 33769.5 2589 18  2.000  1.667  2.333  3.000  2.667  1.333  1.000  1.667   7   6   9  15  12   5   4   6     8 120   150.2   148.5 2
    #{yesterday.year} #{String.pad_leading("#{yesterday.month}", 2, "0")} #{String.pad_leading("#{yesterday.day}", 2, "0")} 33770 33770.5 2589 19  3.333  4.000  2.667  1.000  0.667  1.333  2.000  1.667  18  27  12   4   3   5   7   6    10 115   145.0   143.2 2
    """
  end

  describe "perform/1" do
    test "fetches and upserts solar indices from the last 7 days" do
      Req.Test.stub(SolarClient, fn conn ->
        Req.Test.text(conn, gfz_body_with_recent_dates())
      end)

      assert :ok = SolarIndexWorker.perform(%Oban.Job{})

      assert Repo.aggregate(SolarIndex, :count) == 2
    end

    test "returns error when HTTP request fails" do
      Req.Test.stub(SolarClient, fn conn ->
        Plug.Conn.send_resp(conn, 500, "Internal Server Error")
      end)

      assert {:error, "HTTP 500"} = SolarIndexWorker.perform(%Oban.Job{})
    end

    test "is idempotent — re-running upserts without duplicating" do
      Req.Test.stub(SolarClient, fn conn ->
        Req.Test.text(conn, gfz_body_with_recent_dates())
      end)

      assert :ok = SolarIndexWorker.perform(%Oban.Job{})
      assert :ok = SolarIndexWorker.perform(%Oban.Job{})

      assert Repo.aggregate(SolarIndex, :count) == 2
    end
  end

  describe "perform/1 with date arg" do
    test "fetches and upserts only the matching date" do
      today = Date.to_iso8601(Date.utc_today())

      Req.Test.stub(SolarClient, fn conn ->
        Req.Test.text(conn, gfz_body_with_recent_dates())
      end)

      assert :ok = SolarIndexWorker.perform(%Oban.Job{args: %{"date" => today}})
      assert Repo.aggregate(SolarIndex, :count) == 1
    end

    test "returns error when HTTP request fails" do
      Req.Test.stub(SolarClient, fn conn ->
        Plug.Conn.send_resp(conn, 500, "Internal Server Error")
      end)

      today = Date.to_iso8601(Date.utc_today())
      assert {:error, "HTTP 500"} = SolarIndexWorker.perform(%Oban.Job{args: %{"date" => today}})
    end
  end
end
