defmodule Towerops.Alerts.AlertNotifierTest do
  use Towerops.DataCase, async: false

  import Swoosh.TestAssertions
  import Towerops.AccountsFixtures

  alias Towerops.Alerts.AlertNotifier

  setup do
    owner = user_fixture()
    admin = user_fixture()
    member = user_fixture()

    {:ok, organization} =
      Towerops.Organizations.create_organization(%{name: "Test Org"}, owner.id)

    # Add admin and member
    {:ok, _admin_membership} =
      Towerops.Organizations.create_membership(%{
        organization_id: organization.id,
        user_id: admin.id,
        role: :admin
      })

    {:ok, _member_membership} =
      Towerops.Organizations.create_membership(%{
        organization_id: organization.id,
        user_id: member.id,
        role: :member
      })

    {:ok, site} =
      Towerops.Sites.create_site(%{
        name: "Test Site",
        organization_id: organization.id
      })

    {:ok, device} =
      Towerops.Devices.create_device(%{
        name: "Test Router",
        ip_address: "192.168.1.1",
        site_id: site.id
      })

    # Consume confirmation emails from user creation
    assert_email_sent(subject: "Confirmation instructions")
    assert_email_sent(subject: "Confirmation instructions")
    assert_email_sent(subject: "Confirmation instructions")

    %{owner: owner, admin: admin, member: member, organization: organization, device: device}
  end

  describe "deliver_alert_notification/1" do
    test "sends equipment_down alert to owners and admins", %{
      owner: owner,
      admin: admin,
      organization: organization,
      device: device
    } do
      {:ok, alert} =
        Towerops.Alerts.create_alert(%{
          device_id: device.id,
          alert_type: :device_down,
          triggered_at: DateTime.utc_now(),
          message: "Device is down"
        })

      {:ok, results} = AlertNotifier.deliver_alert_notification(alert)

      # Should send to 2 recipients (owner and admin, not member)
      assert length(results) == 2

      # Verify emails were sent to owner and admin
      assert_email_sent(subject: "[#{organization.name}] Device Down: #{device.name}", to: owner.email)
      assert_email_sent(subject: "[#{organization.name}] Device Down: #{device.name}", to: admin.email)
    end

    test "sends equipment_up alert to owners and admins", %{
      owner: owner,
      admin: admin,
      device: device,
      organization: organization
    } do
      {:ok, alert} =
        Towerops.Alerts.create_alert(%{
          device_id: device.id,
          alert_type: :device_up,
          triggered_at: DateTime.utc_now(),
          message: "Device recovered"
        })

      {:ok, results} = AlertNotifier.deliver_alert_notification(alert)

      # Should send to 2 recipients (owner and admin)
      assert length(results) == 2

      # Verify emails were sent
      assert_email_sent(subject: "[#{organization.name}] Device Recovered: #{device.name}", to: owner.email)
      assert_email_sent(subject: "[#{organization.name}] Device Recovered: #{device.name}", to: admin.email)
    end

    test "equipment_down alert includes correct information", %{
      owner: owner,
      device: device,
      organization: organization
    } do
      {:ok, alert} =
        Towerops.Alerts.create_alert(%{
          device_id: device.id,
          alert_type: :device_down,
          triggered_at: DateTime.utc_now(),
          message: "Device is down"
        })

      {:ok, results} = AlertNotifier.deliver_alert_notification(alert)

      assert length(results) == 2

      # Verify email sent to owner contains all expected information
      assert_email_sent(fn email ->
        email.to |> List.first() |> elem(1) == owner.email &&
          email.subject =~ "Device Down" &&
          email.text_body =~ organization.name &&
          email.text_body =~ device.name &&
          email.text_body =~ device.ip_address &&
          email.text_body =~ "Test Site" &&
          email.text_body =~ "not responding"
      end)
    end

    test "equipment_up alert includes correct information", %{
      device: device,
      organization: organization
    } do
      {:ok, alert} =
        Towerops.Alerts.create_alert(%{
          device_id: device.id,
          alert_type: :device_up,
          triggered_at: DateTime.utc_now(),
          message: "Device recovered"
        })

      {:ok, _results} = AlertNotifier.deliver_alert_notification(alert)

      assert_email_sent(fn email ->
        email.subject =~ "Device Recovered" &&
          email.text_body =~ organization.name &&
          email.text_body =~ device.name &&
          email.text_body =~ device.ip_address &&
          email.text_body =~ "Test Site" &&
          email.text_body =~ "now responding"
      end)
    end

    test "uses correct from address", %{device: device} do
      {:ok, alert} =
        Towerops.Alerts.create_alert(%{
          device_id: device.id,
          alert_type: :device_down,
          triggered_at: DateTime.utc_now(),
          message: "Device is down"
        })

      {:ok, _results} = AlertNotifier.deliver_alert_notification(alert)

      assert_email_sent(fn email ->
        email.from == {"Towerops", "hi@towerops.net"}
      end)
    end
  end
end
