defmodule RefugeWeb.GrpcEventsLive do
  @moduledoc """
  LiveView for displaying gRPC events in real time.
  Shows both lifecycle events and build tool events received by the BES server.
  """
  use RefugeWeb, :live_view
  alias Refuge.GRPC.EventStore
  
  @impl true
  def mount(_params, _session, socket) do
    if connected?(socket) do
      # Subscribe to event updates
      EventStore.subscribe()
    end
    
    # Get initial events
    events = EventStore.get_events()
    
    {:ok, assign(socket, events: events)}
  end

  @impl true
  def handle_info({:new_event, event}, socket) do
    # Add the new event to the list
    updated_events = [event | socket.assigns.events]
    
    # Keep the list at a reasonable size for the UI
    events_to_display = Enum.take(updated_events, 100)
    
    {:noreply, assign(socket, events: events_to_display)}
  end

  @impl true
  def render(assigns) do
    ~H"""
    <div class="container mx-auto px-4 py-8">
      <h1 class="text-3xl font-bold mb-6">gRPC BES Server Events</h1>
      
      <div class="bg-base-200 p-4 mb-6 rounded-lg shadow-md">
        <p>Showing real-time gRPC events from BES server running on port 4001</p>
        <p class="text-sm">
          Connect with Bazel using <code class="bg-base-300 px-1 rounded">--bes_backend=localhost:4001</code>
        </p>
      </div>

      <div class="overflow-x-auto bg-base-100 rounded-lg shadow-lg">
        <table class="table table-zebra w-full">
          <thead>
            <tr>
              <th>Time</th>
              <th>Type</th>
              <th>Details</th>
            </tr>
          </thead>
          <tbody>
            <%= if Enum.empty?(@events) do %>
              <tr>
                <td colspan="3" class="text-center py-8">No events received yet</td>
              </tr>
            <% else %>
              <%= for event <- @events do %>
                <tr class="hover">
                  <td class="whitespace-nowrap">
                    <%= Calendar.strftime(event.timestamp, "%H:%M:%S") %>
                  </td>
                  <td><%= format_event_type(event.type) %></td>
                  <td class="max-w-md truncate">
                    <div class="collapse bg-base-200">
                      <input type="checkbox" class="peer" /> 
                      <div class="collapse-title bg-base-200 text-base-content peer-checked:bg-base-300 peer-checked:text-base-content">
                        <%= event_summary(event) %>
                      </div>
                      <div class="collapse-content bg-base-300 text-base-content"> 
                        <pre class="text-xs overflow-auto max-h-64"><%= inspect(event.data, pretty: true) %></pre>
                      </div>
                    </div>
                  </td>
                </tr>
              <% end %>
            <% end %>
          </tbody>
        </table>
      </div>
    </div>
    """
  end
  
  # Helper functions for formatting event data
  
  defp format_event_type(:lifecycle_event), do: "Lifecycle Event"
  defp format_event_type(:build_tool_event), do: "Build Tool Event"
  defp format_event_type(_), do: "Unknown Event"
  
  defp event_summary(event) do
    case event.type do
      :lifecycle_event -> 
        get_lifecycle_event_summary(event.data)
      :build_tool_event -> 
        get_build_tool_event_summary(event.data)
      _ -> 
        "Unknown event"
    end
  end
  
  defp get_lifecycle_event_summary(data) do
    # Extract project id or other identifying information
    cond do
      data.build_enqueued -> "Build Enqueued: #{data.build_enqueued.project_id}"
      data.invocation_attempt_started -> "Invocation Started: #{data.invocation_attempt_started.attempt_id}"
      data.invocation_attempt_completed -> "Invocation Completed"
      data.build_finished -> "Build Finished"
      true -> "Lifecycle Event"
    end
  end
  
  defp get_build_tool_event_summary(data) do
    # Extract stream id or other identifying information
    stream_id = data.ordered_build_event.stream_id
    "Build Event: #{stream_id.build_id || "unknown"}"
  end
end
