defmodule Towerops.Snmp.NeighborCleanupWorker do
  @moduledoc """
  GenServer that periodically cleans up stale neighbor discovery records.

  Neighbors that haven't been discovered in the last 24 hours are considered stale
  and will be automatically removed from the database.
  """
  use GenServer

  alias Towerops.Devices
  alias Towerops.Snmp

  require Logger

  # Check for stale neighbors every hour
  @cleanup_interval to_timeout(hour: 1)

  # Consider neighbors stale if not seen in 24 hours
  @stale_threshold_hours 24

  def start_link(opts \\ []) do
    GenServer.start_link(__MODULE__, opts, name: __MODULE__)
  end

  @impl true
  def init(_opts) do
    # Schedule first cleanup shortly after startup
    schedule_cleanup(10_000)
    {:ok, %{}}
  end

  @impl true
  def handle_info(:cleanup, state) do
    cleanup_stale_neighbors()
    schedule_cleanup(@cleanup_interval)
    {:noreply, state}
  end

  defp cleanup_stale_neighbors do
    cutoff = DateTime.add(DateTime.utc_now(), -@stale_threshold_hours, :hour)

    Logger.info("Starting neighbor cleanup for records older than #{cutoff}")

    # device IDs with SNMP enabled
    equipment_list = Devices.list_snmp_enabled_devices()

    total_deleted =
      Enum.reduce(equipment_list, 0, fn device, acc ->
        case Snmp.delete_stale_neighbors(device.id, cutoff) do
          {count, _} when count > 0 ->
            Logger.info("Deleted #{count} stale neighbors for device #{device.name} (#{device.id})")

            acc + count

          _ ->
            acc
        end
      end)

    if total_deleted > 0 do
      Logger.info("Neighbor cleanup completed: removed #{total_deleted} stale records")
    else
      Logger.debug("Neighbor cleanup completed: no stale records found")
    end

    :ok
  end

  defp schedule_cleanup(delay) do
    Process.send_after(self(), :cleanup, delay)
  end
end
