defmodule WhoNeedHelpWeb.Presence do
  use Phoenix.Presence,
    otp_app: :who_need_help,
    pubsub_server: WhoNeedHelp.PubSub

  @tracking_topic "browser-tracking-presence"

  def tracking_topic, do: @tracking_topic

  def tracking_key(assignment_id, user_id), do: "#{assignment_id}:#{user_id}"

  def track_browser(pid, assignment_id, user_id, tracking_session_id) do
    key = tracking_key(assignment_id, user_id)

    case track(pid, @tracking_topic, key, %{
           assignment_id: assignment_id,
           user_id: user_id,
           tracking_session_id: tracking_session_id
         }) do
      {:ok, _ref} -> {:ok, key}
      {:error, {:already_tracked, _pid, @tracking_topic, ^key}} -> {:ok, key}
      other -> other
    end
  end

  def untrack_browser(pid, key), do: untrack(pid, @tracking_topic, key)

  @impl Phoenix.Presence
  def init(_options), do: {:ok, %{}}

  @impl Phoenix.Presence
  def handle_metas(@tracking_topic, %{leaves: leaves}, presences, state) do
    Enum.each(leaves, fn {key, %{metas: metas}} ->
      if not Map.has_key?(presences, key) do
        case List.first(metas) do
          %{
            assignment_id: assignment_id,
            user_id: user_id,
            tracking_session_id: tracking_session_id
          } ->
            WhoNeedHelp.TrackingPresenceCleanup.maybe_stop(
              key,
              assignment_id,
              user_id,
              tracking_session_id
            )

          _other ->
            :ok
        end
      end
    end)

    {:ok, state}
  end

  def handle_metas(_topic, _diff, _presences, state), do: {:ok, state}
end
