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

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

  alias Towerops.Gaiia
  alias Towerops.Gaiia.ImpactAnalysis

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

  describe "analyze_device_impact/2" do
    test "returns empty impact when device has no gaiia mapping", %{org: org} do
      device = device_fixture(%{organization_id: org.id, name: "Unmapped Router"})

      result = ImpactAnalysis.analyze_device_impact(org.id, device.id)

      assert result.device_level == nil
      assert result.site_level == nil
      assert result.total_subscribers == 0
      assert result.total_mrr == Decimal.new("0")
    end

    test "returns device-level impact when device is mapped to inventory item with account", %{
      org: org
    } do
      device = device_fixture(%{organization_id: org.id, name: "Mapped Router"})

      {:ok, _account} =
        Gaiia.upsert_account(org.id, %{
          gaiia_id: "gaiia-acct-1",
          name: "John Smith",
          status: "active",
          mrr: Decimal.new("79.99")
        })

      {:ok, _item} =
        Gaiia.upsert_inventory_item(org.id, %{
          gaiia_id: "gaiia-inv-1",
          name: "Router One",
          assigned_account_gaiia_id: "gaiia-acct-1"
        })

      Gaiia.update_inventory_item_mapping(
        Gaiia.get_inventory_item(org.id, "gaiia-inv-1"),
        %{device_id: device.id}
      )

      result = ImpactAnalysis.analyze_device_impact(org.id, device.id)

      assert result.device_level
      assert result.device_level.subscriber_count == 1
      assert Decimal.equal?(result.device_level.mrr, Decimal.new("79.99"))
      assert result.total_subscribers == 1
    end

    test "returns site-level impact when device site is mapped to gaiia network site", %{
      org: org
    } do
      device = device_fixture(%{organization_id: org.id, name: "Tower Router"})
      device = Towerops.Repo.preload(device, :site)

      {:ok, _network_site} =
        Gaiia.upsert_network_site(org.id, %{
          gaiia_id: "gaiia-site-1",
          name: "Tower 3",
          account_count: 147,
          total_mrr: Decimal.new("17640.00")
        })

      Gaiia.update_network_site_mapping(
        Gaiia.get_network_site(org.id, "gaiia-site-1"),
        %{site_id: device.site_id}
      )

      result = ImpactAnalysis.analyze_device_impact(org.id, device.id)

      assert result.site_level
      assert result.site_level.subscriber_count == 147
      assert Decimal.equal?(result.site_level.mrr, Decimal.new("17640.00"))
      assert result.site_level.site_name == "Tower 3"
    end

    test "combines device and site level impacts", %{org: org} do
      device = device_fixture(%{organization_id: org.id, name: "Tower AP"})
      device = Towerops.Repo.preload(device, :site)

      {:ok, _account} =
        Gaiia.upsert_account(org.id, %{
          gaiia_id: "gaiia-acct-1",
          name: "Direct Subscriber",
          status: "active",
          mrr: Decimal.new("50.00")
        })

      {:ok, _item} =
        Gaiia.upsert_inventory_item(org.id, %{
          gaiia_id: "gaiia-inv-1",
          name: "AP One",
          assigned_account_gaiia_id: "gaiia-acct-1"
        })

      Gaiia.update_inventory_item_mapping(
        Gaiia.get_inventory_item(org.id, "gaiia-inv-1"),
        %{device_id: device.id}
      )

      {:ok, _network_site} =
        Gaiia.upsert_network_site(org.id, %{
          gaiia_id: "gaiia-site-1",
          name: "Tower 3",
          account_count: 50,
          total_mrr: Decimal.new("5000.00")
        })

      Gaiia.update_network_site_mapping(
        Gaiia.get_network_site(org.id, "gaiia-site-1"),
        %{site_id: device.site_id}
      )

      result = ImpactAnalysis.analyze_device_impact(org.id, device.id)

      assert result.device_level
      assert result.site_level
      # Total should use the broadest (site-level) subscriber count
      assert result.total_subscribers == 50
      assert Decimal.equal?(result.total_mrr, Decimal.new("5000.00"))
    end

    test "returns analyzable result structure", %{org: org} do
      device = device_fixture(%{organization_id: org.id, name: "Test Router"})

      result = ImpactAnalysis.analyze_device_impact(org.id, device.id)

      assert is_map(result)
      assert Map.has_key?(result, :device_level)
      assert Map.has_key?(result, :site_level)
      assert Map.has_key?(result, :total_subscribers)
      assert Map.has_key?(result, :total_mrr)
      assert Map.has_key?(result, :analyzed_at)
    end
  end
end
