defmodule Microwaveprop.Propagation.RainScatterClassifierTest do
  use ExUnit.Case, async: true

  alias Microwaveprop.Propagation.RainScatterClassifier

  defp inputs(overrides \\ %{}) do
    base = %{
      band_mhz: 10_000,
      distance_km: 250.0,
      radar: %{max_dbz: 42.0, heavy_rain_pixel_count: 12, coverage_pct: 80.0},
      duct_either_endpoint: false
    }

    Map.merge(base, overrides)
  end

  describe "classify/1" do
    test "10 GHz, short path, heavy rain in CV, no duct -> :likely_rainscatter" do
      assert RainScatterClassifier.classify(inputs()) == :likely_rainscatter
    end

    test "duct at either endpoint overrides -> :tropo_duct even with rain" do
      assert RainScatterClassifier.classify(inputs(%{duct_either_endpoint: true})) == :tropo_duct
    end

    test "no rain, no duct, 10 GHz -> :troposcatter" do
      inp = inputs(%{radar: %{max_dbz: 5.0, heavy_rain_pixel_count: 0, coverage_pct: 90.0}})
      assert RainScatterClassifier.classify(inp) == :troposcatter
    end

    test "path too long (> 800 km) -> :troposcatter regardless of rain" do
      assert RainScatterClassifier.classify(inputs(%{distance_km: 1000.0})) == :troposcatter
    end

    test "band above rainscatter window (24 GHz) -> not rainscatter" do
      result = RainScatterClassifier.classify(inputs(%{band_mhz: 24_000}))
      assert result in [:tropo_duct, :troposcatter, :unknown]
      refute result == :likely_rainscatter
    end

    test "band below 5 GHz -> not rainscatter (scattering efficiency drops fast)" do
      result = RainScatterClassifier.classify(inputs(%{band_mhz: 1_296}))
      refute result == :likely_rainscatter
    end

    test "no radar coverage at all -> :unknown (can't distinguish)" do
      inp = inputs(%{radar: nil, duct_either_endpoint: false})
      assert RainScatterClassifier.classify(inp) == :unknown
    end

    test "radar coverage is too spotty -> :unknown" do
      inp = inputs(%{radar: %{max_dbz: 42.0, heavy_rain_pixel_count: 1, coverage_pct: 5.0}})
      assert RainScatterClassifier.classify(inp) == :unknown
    end

    test "light rain (25-35 dBZ) counts as rainscatter-possible, not probable" do
      inp = inputs(%{radar: %{max_dbz: 28.0, heavy_rain_pixel_count: 0, coverage_pct: 80.0}})
      # 28 dBZ -> rainscatter_possible; absence of heavy cells is the discriminator
      assert RainScatterClassifier.classify(inp) == :rainscatter_possible
    end
  end
end
