defmodule Towerops.Preseem.ClientTest do
  use ExUnit.Case, async: true

  alias Towerops.Preseem.Client

  describe "test_connection/1" do
    test "returns ok when API responds with 200" do
      Req.Test.stub(Client, fn conn ->
        assert conn.request_path == "/model/v1/access_points"
        assert conn.query_string =~ "limit=100"

        Req.Test.json(conn, %{
          "data" => [%{"id" => 1, "name" => "Test AP"}],
          "paginator" => %{"page" => 1, "page_count" => 1, "limit" => 100, "total_count" => 1}
        })
      end)

      assert {:ok, _body} = Client.test_connection("valid-api-key")
    end

    test "returns error for 401 unauthorized" do
      Req.Test.stub(Client, fn conn ->
        conn
        |> Plug.Conn.put_status(401)
        |> Req.Test.json(%{"error" => "unauthorized"})
      end)

      assert {:error, :unauthorized} = Client.test_connection("bad-key")
    end

    test "returns error for 403 forbidden" do
      Req.Test.stub(Client, fn conn ->
        conn
        |> Plug.Conn.put_status(403)
        |> Req.Test.json(%{"error" => "forbidden"})
      end)

      assert {:error, :forbidden} = Client.test_connection("restricted-key")
    end
  end

  describe "list_access_points/1" do
    test "returns list of access point scores on success" do
      Req.Test.stub(Client, fn conn ->
        assert conn.request_path == "/model/v1/access_point_scores"

        Req.Test.json(conn, [
          %{
            "element_uuid" => "uuid-1",
            "name" => "Tower1-AP1",
            "system_mac_address" => "AA:BB:CC:DD:EE:FF",
            "management_ip" => "10.0.0.1",
            "model_name" => "AF60",
            "firmware" => "4.3.2",
            "rf_score" => 78.0,
            "ap_health_score" => 92.5,
            "subscriber_capacity" => 85,
            "connections" => 30,
            "airtime_remaining_tx" => 55
          },
          %{
            "element_uuid" => "uuid-2",
            "name" => "Tower1-AP2",
            "management_ip" => "10.0.0.2"
          }
        ])
      end)

      assert {:ok, [ap1, ap2]} = Client.list_access_points("valid-key")
      assert ap1["element_uuid"] == "uuid-1"
      assert ap2["element_uuid"] == "uuid-2"
    end

    test "handles wrapped response with data key" do
      Req.Test.stub(Client, fn conn ->
        Req.Test.json(conn, %{
          "data" => [
            %{"element_uuid" => "uuid-1", "name" => "AP1"}
          ]
        })
      end)

      assert {:ok, [ap]} = Client.list_access_points("valid-key")
      assert ap["element_uuid"] == "uuid-1"
    end

    test "handles single object response by wrapping in list" do
      Req.Test.stub(Client, fn conn ->
        Req.Test.json(conn, %{
          "element_uuid" => "uuid-1",
          "name" => "Single AP"
        })
      end)

      assert {:ok, [ap]} = Client.list_access_points("valid-key")
      assert ap["element_uuid"] == "uuid-1"
    end

    test "returns error for 401" do
      Req.Test.stub(Client, fn conn ->
        conn |> Plug.Conn.put_status(401) |> Req.Test.json(%{"error" => "unauthorized"})
      end)

      assert {:error, :unauthorized} = Client.list_access_points("bad-key")
    end
  end

  describe "list_access_points_basic/1" do
    test "fetches all pages of access points" do
      Req.Test.stub(Client, fn conn ->
        assert conn.request_path == "/model/v1/access_points"
        params = Plug.Conn.fetch_query_params(conn).query_params

        case params["page"] do
          nil ->
            Req.Test.json(conn, %{
              "data" => [%{"id" => 1, "name" => "AP1"}],
              "paginator" => %{"page" => 1, "page_count" => 2, "limit" => 500, "total_count" => 2}
            })

          "2" ->
            Req.Test.json(conn, %{
              "data" => [%{"id" => 2, "name" => "AP2"}],
              "paginator" => %{"page" => 2, "page_count" => 2, "limit" => 500, "total_count" => 2}
            })
        end
      end)

      assert {:ok, aps} = Client.list_access_points_basic("valid-key")
      assert length(aps) == 2
    end

    test "returns error for 401" do
      Req.Test.stub(Client, fn conn ->
        conn |> Plug.Conn.put_status(401) |> Req.Test.json(%{"error" => "unauthorized"})
      end)

      assert {:error, :unauthorized} = Client.list_access_points_basic("bad-key")
    end
  end
end
