defmodule SomethingErlang.Grover do
  use GenServer

  alias SomethingErlang.AwfulApi
  require Logger

  def mount(user) do
    {:ok, _pid} =
      DynamicSupervisor.start_child(
        SomethingErlang.Supervisor.Grovers,
        {__MODULE__, [self(), user]}
      )
  end

  def get_thread!(thread_id, page_number) do
    GenServer.call(via(self()), {:show_thread, thread_id, page_number})
  end

  def get_bookmarks!(page_number) do
    GenServer.call(via(self()), {:show_bookmarks, page_number})
  end

  def start_link([lv_pid, user]) do
    GenServer.start_link(
      __MODULE__,
      [lv_pid, user],
      name: via(lv_pid)
    )
  end

  @impl true
  def init([pid, user]) do
    %{bbuserid: userid, bbpassword: userhash} = user

    initial_state = %{
      lv_pid: pid,
      user: %{id: userid, hash: userhash}
    }

    Logger.debug("init #{userid} #{inspect(pid)}")
    Process.monitor(pid)
    {:ok, initial_state}
  end

  @impl true
  def handle_call({:show_thread, thread_id, page_number}, _from, state) do
    thread = AwfulApi.parsed_thread(thread_id, page_number, state.user)
    {:reply, thread, state}
  end

  @impl true
  def handle_call({:show_bookmarks, _page_number}, _from, state) do
    bookmarks = AwfulApi.bookmarks(state.user)
    {:reply, bookmarks, state}
  end

  @impl true
  def handle_info({:DOWN, _ref, :process, _object, reason}, state) do
    Logger.debug("received :DOWN from: #{inspect(state.lv_pid)} reason: #{inspect(reason)}")

    case reason do
      {:shutdown, _} -> {:stop, :normal, state}
      :killed -> {:stop, :normal, state}
      _ -> {:noreply, state}
    end
  end

  defp via(lv_pid),
    do: {:via, Registry, {SomethingErlang.Registry.Grovers, lv_pid}}
end