defmodule Towerops.Gaiia.ActionsTest do
  use Towerops.DataCase, async: true

  import Towerops.AccountsFixtures
  import Towerops.DevicesFixtures
  import Towerops.OrganizationsFixtures

  alias Towerops.Gaiia.Actions
  alias Towerops.Gaiia.Client
  alias Towerops.Integrations

  setup do
    user = user_fixture()
    org = organization_fixture(user.id)

    {:ok, integration} =
      Integrations.create_integration(org.id, %{
        provider: "gaiia",
        enabled: true,
        credentials: %{"api_key" => "test-key"}
      })

    %{org: org, integration: integration}
  end

  describe "create_ticket_for_alert/3" do
    test "creates a ticket via Gaiia API and returns ticket ID", %{org: org} do
      device = device_fixture(%{organization_id: org.id, name: "Tower Router"})

      alert = %{
        id: Ecto.UUID.generate(),
        device: device,
        alert_type: :device_down,
        message: "Device is not responding to SNMP",
        triggered_at: DateTime.utc_now()
      }

      Req.Test.stub(Client, fn conn ->
        {:ok, body, conn} = Plug.Conn.read_body(conn)
        decoded = Jason.decode!(body)
        assert decoded["query"] =~ "createExternalTicket"

        Req.Test.json(conn, %{
          "data" => %{
            "createExternalTicket" => %{
              "id" => "gaiia-ticket-123",
              "subject" => "Device Down: Tower Router"
            }
          }
        })
      end)

      assert {:ok, "gaiia-ticket-123"} = Actions.create_ticket_for_alert(org.id, alert)
    end

    test "returns error when no integration exists" do
      org_id = Ecto.UUID.generate()

      alert = %{
        id: Ecto.UUID.generate(),
        alert_type: :device_down,
        device: %{name: "Test"},
        message: "Down",
        triggered_at: DateTime.utc_now()
      }

      assert {:error, :no_integration} = Actions.create_ticket_for_alert(org_id, alert)
    end
  end

  describe "create_subscriber_note/4" do
    test "creates a note on a Gaiia account", %{org: org} do
      Req.Test.stub(Client, fn conn ->
        {:ok, body, conn} = Plug.Conn.read_body(conn)
        decoded = Jason.decode!(body)
        assert decoded["query"] =~ "createNote"

        Req.Test.json(conn, %{
          "data" => %{
            "createNote" => %{
              "id" => "gaiia-note-456"
            }
          }
        })
      end)

      assert {:ok, "gaiia-note-456"} =
               Actions.create_subscriber_note(org.id, "gaiia-acct-1", "Outage affecting Tower 3")
    end

    test "returns error when no integration exists" do
      org_id = Ecto.UUID.generate()

      assert {:error, :no_integration} =
               Actions.create_subscriber_note(org_id, "gaiia-acct-1", "note")
    end
  end

  describe "update_inventory_item/4" do
    test "pushes field updates to Gaiia inventory item", %{org: org} do
      Req.Test.stub(Client, fn conn ->
        {:ok, body, conn} = Plug.Conn.read_body(conn)
        decoded = Jason.decode!(body)
        assert decoded["query"] =~ "updateInventoryItem"

        Req.Test.json(conn, %{
          "data" => %{
            "updateInventoryItem" => %{
              "id" => "gaiia-inv-1",
              "ipAddress" => "10.0.0.5"
            }
          }
        })
      end)

      assert {:ok, _data} =
               Actions.update_inventory_item(org.id, "gaiia-inv-1", %{ip_address: "10.0.0.5"})
    end

    test "returns error when no integration exists" do
      org_id = Ecto.UUID.generate()

      assert {:error, :no_integration} =
               Actions.update_inventory_item(org_id, "gaiia-inv-1", %{ip_address: "10.0.0.5"})
    end
  end
end
