defmodule ToweropsWeb.SiteLive.Show do
  @moduledoc false
  use ToweropsWeb, :live_view

  alias Towerops.Devices
  alias Towerops.Monitoring
  alias Towerops.Sites

  @impl true
  def mount(_params, _session, socket) do
    {:ok, socket}
  end

  @impl true
  def handle_params(%{"id" => id}, _, socket) do
    organization = socket.assigns.current_organization
    site = Sites.get_organization_site!(organization.id, id)
    device = Devices.list_site_devices(site.id)
    latency_chart_data = load_site_latency_chart_data(device)

    {:noreply,
     socket
     |> assign(:page_title, site.name)
     |> assign(:site, site)
     |> assign(:device, device)
     |> assign(:latency_chart_data, latency_chart_data)}
  end

  defp load_site_latency_chart_data(devices) do
    if Enum.empty?(devices) do
      nil
    else
      twenty_four_hours_ago = DateTime.add(DateTime.utc_now(), -24, :hour)

      datasets =
        devices
        |> Enum.map(fn device ->
          checks =
            device.id
            |> Monitoring.get_latency_data(since: twenty_four_hours_ago, limit: 1000)
            |> Enum.reverse()

          %{
            label: device.name,
            data: Enum.map(checks, &latency_check_to_data_point/1)
          }
        end)
        |> Enum.reject(fn dataset -> Enum.empty?(dataset.data) end)

      if Enum.empty?(datasets) do
        nil
      else
        Jason.encode!(%{datasets: datasets})
      end
    end
  end

  defp latency_check_to_data_point(check) do
    %{
      x: DateTime.to_unix(check.checked_at, :millisecond),
      y: check.response_time_ms
    }
  end
end
