defmodule Towerops.Preseem.AccessPointTest do
  use Towerops.DataCase, async: true

  import Towerops.AccountsFixtures
  import Towerops.OrganizationsFixtures

  alias Towerops.Preseem.AccessPoint

  setup do
    user = user_fixture()
    org = organization_fixture(user.id)
    %{organization: org}
  end

  describe "changeset/2" do
    test "valid changeset with required fields", %{organization: org} do
      attrs = %{organization_id: org.id, preseem_id: "ap-123", name: "Tower1-AP1"}
      changeset = AccessPoint.changeset(%AccessPoint{}, attrs)
      assert changeset.valid?
    end

    test "requires organization_id" do
      changeset = AccessPoint.changeset(%AccessPoint{}, %{preseem_id: "ap-1"})
      refute changeset.valid?
      assert "can't be blank" in errors_on(changeset).organization_id
    end

    test "requires preseem_id" do
      changeset = AccessPoint.changeset(%AccessPoint{}, %{organization_id: Ecto.UUID.generate()})
      refute changeset.valid?
      assert "can't be blank" in errors_on(changeset).preseem_id
    end

    test "validates match_confidence is a known value" do
      attrs = %{organization_id: Ecto.UUID.generate(), preseem_id: "ap-1", match_confidence: "bogus"}
      changeset = AccessPoint.changeset(%AccessPoint{}, attrs)
      refute changeset.valid?
      assert "is invalid" in errors_on(changeset).match_confidence
    end

    test "accepts all valid match_confidence values" do
      for confidence <- ~w(auto_mac auto_ip auto_hostname manual ambiguous unmatched) do
        attrs = %{organization_id: Ecto.UUID.generate(), preseem_id: "ap-1", match_confidence: confidence}
        changeset = AccessPoint.changeset(%AccessPoint{}, attrs)
        assert changeset.valid?, "Expected #{confidence} to be valid"
      end
    end

    test "enforces unique preseem_id per org", %{organization: org} do
      attrs = %{organization_id: org.id, preseem_id: "ap-123"}
      {:ok, _} = %AccessPoint{} |> AccessPoint.changeset(attrs) |> Repo.insert()
      assert {:error, changeset} = %AccessPoint{} |> AccessPoint.changeset(attrs) |> Repo.insert()
      assert "has already been taken" in errors_on(changeset).preseem_id
    end

    test "stores and retrieves raw_data", %{organization: org} do
      raw = %{"extra_field" => "value", "nested" => %{"key" => 42}}
      attrs = %{organization_id: org.id, preseem_id: "ap-raw", raw_data: raw}
      {:ok, ap} = %AccessPoint{} |> AccessPoint.changeset(attrs) |> Repo.insert()
      reloaded = Repo.get!(AccessPoint, ap.id)
      assert reloaded.raw_data == raw
    end

    test "stores numeric scores", %{organization: org} do
      attrs = %{
        organization_id: org.id,
        preseem_id: "ap-scores",
        qoe_score: 85.5,
        capacity_score: 72.0,
        rf_score: 90.1,
        busy_hours: 4,
        airtime_utilization: 65.3,
        subscriber_count: 42
      }

      {:ok, ap} = %AccessPoint{} |> AccessPoint.changeset(attrs) |> Repo.insert()
      reloaded = Repo.get!(AccessPoint, ap.id)
      assert reloaded.qoe_score == 85.5
      assert reloaded.subscriber_count == 42
    end
  end
end
