defmodule Towerops.Accounts.UserNotifier do
  @moduledoc """
  Email notification service for user authentication workflows.

  Sends emails for password reset, email confirmation, and other user events.
  """

  use Gettext, backend: ToweropsWeb.Gettext

  import Swoosh.Email
  import ToweropsWeb.GettextHelpers

  alias Towerops.Accounts.User
  alias Towerops.Mailer

  require Logger

  # Delivers the email using the application mailer.
  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("User email sent to #{recipient}: #{subject}")
        {:ok, email}

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

  @doc """
  Deliver instructions to update a user email.
  """
  def deliver_update_email_instructions(user, url) do
    subject = t_email("Update email instructions")

    body =
      t_email(
        """
        Hi %{email},

        You can change your email by visiting the URL below:

        %{url}

        If you didn't request this change, please ignore this.
        """,
        email: user.email,
        url: url
      )

    deliver(user.email, subject, body)
  end

  @doc """
  Deliver instructions to log in with a magic link.
  """
  def deliver_login_instructions(user, url) do
    case user do
      %User{confirmed_at: nil} -> deliver_confirmation_instructions(user, url)
      _ -> deliver_magic_link_instructions(user, url)
    end
  end

  defp deliver_magic_link_instructions(user, url) do
    subject = t_email("Log in instructions")

    body =
      t_email(
        """
        Hi %{email},

        You can log into your account by visiting the URL below:

        %{url}

        If you didn't request this email, please ignore this.
        """,
        email: user.email,
        url: url
      )

    deliver(user.email, subject, body)
  end

  defp deliver_confirmation_instructions(user, url) do
    subject = t_email("Confirmation instructions")

    body =
      t_email(
        """
        Hi %{email},

        You can confirm your account by visiting the URL below:

        %{url}

        If you didn't create an account with us, please ignore this.
        """,
        email: user.email,
        url: url
      )

    deliver(user.email, subject, body)
  end

  @doc """
  Deliver instructions to reset a user password.
  """
  def deliver_reset_password_instructions(user, url) do
    subject = t_email("Reset password instructions")

    body =
      t_email(
        """
        Hi %{email},

        You can reset your password by visiting the URL below:

        %{url}

        If you didn't request this change, please ignore this.

        This link will expire in 1 hour.
        """,
        email: user.email,
        url: url
      )

    deliver(user.email, subject, body)
  end
end
