defmodule Towerops.Alerts.AlertNotifier do
  @moduledoc """
  Delivers alert notifications via email.
  """

  import Swoosh.Email

  alias Towerops.Alerts.Alert
  alias Towerops.Devices
  alias Towerops.Mailer
  alias Towerops.Organizations

  require Logger

  @doc """
  Deliver alert notification to organization members.

  Returns list of sent emails for tracking.
  """
  @spec deliver_alert_notification(Alert.t()) ::
          {:ok, [{:ok, Swoosh.Email.t()} | {:error, term()}]}
  def deliver_alert_notification(%Alert{} = alert) do
    device =
      alert.device_id
      |> Devices.get_device!()
      |> Towerops.Repo.preload(site: :organization)

    site = device.site
    organization = site.organization

    # Get all owners and admins who should receive alerts
    recipients = Organizations.list_organization_notification_recipients(organization.id)

    results =
      Enum.map(recipients, fn user ->
        case alert.alert_type do
          :device_down -> deliver_equipment_down_alert(user.email, device, organization)
          :device_up -> deliver_equipment_up_alert(user.email, device, organization)
        end
      end)

    {:ok, results}
  end

  defp deliver_equipment_down_alert(recipient_email, device, organization) do
    subject = "[#{organization.name}] Device Down: #{device.name}"

    check_method = if device.snmp_enabled, do: "SNMP", else: "ping"

    body = """

    ==============================

    ALERT: Device Down

    Organization: #{organization.name}
    Device: #{device.name}
    IP Address: #{device.ip_address}
    Site: #{device.site.name}

    The device is not responding to #{check_method} checks.

    Please investigate as soon as possible.

    ==============================
    """

    deliver(recipient_email, subject, body)
  end

  defp deliver_equipment_up_alert(recipient_email, device, organization) do
    subject = "[#{organization.name}] Device Recovered: #{device.name}"

    check_method = if device.snmp_enabled, do: "SNMP", else: "ping"

    body = """

    ==============================

    RESOLVED: Device Recovered

    Organization: #{organization.name}
    Device: #{device.name}
    IP Address: #{device.ip_address}
    Site: #{device.site.name}

    The device is now responding to #{check_method} checks.

    ==============================
    """

    deliver(recipient_email, subject, body)
  end

  defp deliver(recipient, subject, body) do
    from_address = Application.get_env(:towerops, :mailer_from, {"Towerops", "hi@towerops.net"})

    email =
      new()
      |> to(recipient)
      |> from(from_address)
      |> subject(subject)
      |> text_body(body)

    case Mailer.deliver(email) do
      {:ok, _metadata} ->
        Logger.info("Alert email sent to #{recipient}: #{subject}")
        {:ok, email}

      {:error, reason} = error ->
        Logger.error("Failed to send alert email to #{recipient}: #{inspect(reason)}")
        error
    end
  end
end
