defmodule Berrypod.Newsletter.ScheduledCampaignWorker do
  @moduledoc """
  Picks up scheduled campaigns that are due and triggers sending.

  Runs every 5 minutes via cron. Simpler than using Oban's schedule_in
  because it lets admins cancel scheduled campaigns by changing status.
  """

  use Oban.Worker, queue: :newsletter, max_attempts: 1

  import Ecto.Query

  alias Berrypod.Newsletter
  alias Berrypod.Newsletter.Campaign
  alias Berrypod.Repo

  require Logger

  @impl Oban.Worker
  def perform(%Oban.Job{}) do
    now = DateTime.utc_now() |> DateTime.truncate(:second)

    campaigns =
      from(c in Campaign,
        where: c.status == "scheduled" and c.scheduled_at <= ^now
      )
      |> Repo.all()

    for campaign <- campaigns do
      Logger.info("Triggering scheduled campaign #{campaign.id}: #{campaign.subject}")
      Newsletter.send_campaign_now(campaign)
    end

    :ok
  end
end
