defmodule Microwaveprop.SpaceWeather.SwpcClientTest do
  use ExUnit.Case, async: true

  alias Microwaveprop.SpaceWeather.SwpcClient

  describe "parse_kp/1" do
    test "decodes the SWPC planetary_k_index_1m fixture" do
      body = File.read!("test/fixtures/swpc/kp_sample.json")

      assert {:ok, rows} = SwpcClient.parse_kp(body)
      assert length(rows) == 10

      first = hd(rows)
      assert first.valid_time == ~U[2026-04-15 13:49:00Z]
      assert first.kp_index == 0
      assert_in_delta first.estimated_kp, 0.33, 0.001
    end

    test "returns {:error, _} for malformed bodies" do
      assert {:error, _} = SwpcClient.parse_kp("not json")
      assert {:error, _} = SwpcClient.parse_kp(~s({"not": "an array"}))
    end
  end

  describe "parse_f107/1" do
    test "decodes the SWPC f107_cm_flux fixture" do
      body = File.read!("test/fixtures/swpc/f107_sample.json")

      assert {:ok, rows} = SwpcClient.parse_f107(body)
      assert length(rows) == 10

      first = hd(rows)
      assert first.valid_time == ~U[2026-04-15 17:00:00Z]
      assert first.frequency_mhz == 2800
      assert first.flux_sfu == 112.0
      assert first.reporting_schedule == "Morning"
    end

    test "keeps nullable historical stats as nil when absent" do
      body = File.read!("test/fixtures/swpc/f107_sample.json")
      {:ok, [first | _]} = SwpcClient.parse_f107(body)
      assert first.ninety_day_mean == nil
    end
  end

  describe "parse_xrays/1" do
    test "decodes the GOES xrays-1-day fixture, keeping the 0.1-0.8nm band only" do
      body = File.read!("test/fixtures/swpc/xrays_sample.json")

      assert {:ok, rows} = SwpcClient.parse_xrays(body)
      # Fixture has 12 records (6 timestamps × 2 bands). We keep the
      # long-wavelength band (0.1-0.8nm) which is the standard SWF /
      # D-layer absorption proxy.
      assert length(rows) == 6
      assert Enum.all?(rows, fn r -> r.energy_band == "0.1-0.8nm" end)

      first = hd(rows)
      assert first.valid_time == ~U[2026-04-14 19:49:00Z]
      assert first.satellite == 18
      assert_in_delta first.flux_wm2, 3.523e-07, 1.0e-09
    end
  end
end
