defmodule Microwaveprop.Terrain.TerrainProfileTest do
  use Microwaveprop.DataCase, async: true

  alias Microwaveprop.Radio.Contact
  alias Microwaveprop.Terrain.TerrainProfile

  @qso_attrs %{
    station1: "W5XD",
    station2: "K5TR",
    qso_timestamp: ~U[2026-03-28 18:00:00Z],
    mode: "CW",
    band: Decimal.new("1296"),
    pos1: %{"lat" => 32.9, "lon" => -97.0},
    pos2: %{"lat" => 30.3, "lon" => -97.7}
  }

  defp create_contact do
    {:ok, contact} =
      %Contact{}
      |> Contact.changeset(@qso_attrs)
      |> Repo.insert()

    contact
  end

  describe "changeset/2" do
    test "valid with required fields" do
      contact = create_contact()

      attrs = %{
        contact_id: contact.id,
        sample_count: 65,
        path_points: [%{"lat" => 32.9, "lon" => -97.0, "elev" => 200.0, "dist_km" => 0.0}],
        verdict: "CLEAR"
      }

      changeset = TerrainProfile.changeset(%TerrainProfile{}, attrs)
      assert changeset.valid?
    end

    test "invalid without required fields" do
      changeset = TerrainProfile.changeset(%TerrainProfile{}, %{})
      refute changeset.valid?

      errors = errors_on(changeset)
      assert errors[:contact_id]
      assert errors[:sample_count]
      assert errors[:path_points]
      assert errors[:verdict]
    end

    test "valid with all optional fields" do
      contact = create_contact()

      attrs = %{
        contact_id: contact.id,
        sample_count: 65,
        path_points: [%{"lat" => 32.9, "lon" => -97.0, "elev" => 200.0, "dist_km" => 0.0}],
        verdict: "BLOCKED",
        max_elevation_m: 450.0,
        min_clearance_m: -12.5,
        diffraction_db: 8.3,
        fresnel_hit_count: 3,
        obstructed_count: 1
      }

      changeset = TerrainProfile.changeset(%TerrainProfile{}, attrs)
      assert changeset.valid?
    end

    test "enforces unique contact_id constraint on insert" do
      contact = create_contact()

      attrs = %{
        contact_id: contact.id,
        sample_count: 65,
        path_points: [],
        verdict: "CLEAR"
      }

      {:ok, _} =
        %TerrainProfile{}
        |> TerrainProfile.changeset(attrs)
        |> Repo.insert()

      {:error, changeset} =
        %TerrainProfile{}
        |> TerrainProfile.changeset(attrs)
        |> Repo.insert()

      assert errors_on(changeset)[:contact_id]
    end
  end
end
