defmodule Microwaveprop.Radio.EditNotifier do
  @moduledoc false
  import Swoosh.Email

  alias Microwaveprop.Mailer

  def deliver_edit_approved(edit) do
    edit = Microwaveprop.Repo.preload(edit, [:user, :contact])
    contact = edit.contact

    body = """
    ==============================

    Hi #{edit.user.callsign},

    Your suggested edit to the contact #{contact.station1} <-> #{contact.station2}
    (#{format_band(contact.band)}, #{format_ts(contact.qso_timestamp)}) has been APPROVED
    and applied.

    Changes applied:
    #{format_changes(edit.proposed_changes)}
    #{format_note(edit.admin_note)}
    View the contact: #{url()}/contacts/#{contact.id}

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

    deliver(edit.user.email, "Your contact edit was approved", body)
  end

  def deliver_edit_rejected(edit) do
    edit = Microwaveprop.Repo.preload(edit, [:user, :contact])
    contact = edit.contact

    body = """
    ==============================

    Hi #{edit.user.callsign},

    Your suggested edit to the contact #{contact.station1} <-> #{contact.station2}
    (#{format_band(contact.band)}, #{format_ts(contact.qso_timestamp)}) has been REJECTED.

    Proposed changes:
    #{format_changes(edit.proposed_changes)}
    #{format_note(edit.admin_note)}
    View the contact: #{url()}/contacts/#{contact.id}

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

    deliver(edit.user.email, "Your contact edit was rejected", body)
  end

  defp deliver(recipient, subject, body) do
    email =
      new()
      |> to(recipient)
      |> Mailer.apply_defaults()
      |> subject(subject)
      |> text_body(body)

    with {:ok, _metadata} <- Mailer.deliver(email) do
      {:ok, email}
    end
  end

  defp url do
    MicrowavepropWeb.Endpoint.url()
  end

  defp format_band(nil), do: "?"

  defp format_band(band) do
    mhz = Decimal.to_integer(band)
    if mhz >= 1000, do: "#{div(mhz, 1000)} GHz", else: "#{mhz} MHz"
  end

  defp format_ts(nil), do: "?"
  defp format_ts(ts), do: Calendar.strftime(ts, "%Y-%m-%d %H:%M UTC")

  defp format_changes(changes) do
    Enum.map_join(changes, "\n", fn {field, value} -> "  - #{field}: #{value}" end)
  end

  defp format_note(nil), do: ""
  defp format_note(""), do: ""
  defp format_note(note), do: "\nAdmin note: #{note}\n"
end
