defmodule MoldbWeb.SearchComponent do
  use MoldbWeb, :live_component
  alias Moldb.Search

  @suggestion_limit 5
  @debounce_time 300

  @impl true
  def render(assigns) do
    ~H"""
    <div id="search-component" phx-hook="ClickOutside">
      <form phx-submit="search" phx-target={@myself} class="relative">
        <div class="relative">
          <input type="text"
                 name="query"
                 value={@query}
                 placeholder="Search..."
                 autocomplete="off"
                 phx-keyup="suggest"
                 phx-debounce={@debounce_time}
                 phx-target={@myself}
                 phx-blur="hide_suggestions"
                 class="w-full p-4 pr-12 text-sm border-gray-200 rounded-lg shadow-sm focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
          />
          <button type="submit" class="absolute inset-y-0 right-0 px-4 text-gray-600 hover:text-blue-600">
            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
              <path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" />
            </svg>
          </button>
        </div>

        <%= if @show_suggestions and @suggestions != [] do %>
          <div class="absolute z-10 w-full mt-2 bg-white border border-gray-200 rounded-lg shadow-lg">
            <%= for suggestion <- @suggestions do %>
              <div class="px-4 py-2 cursor-pointer hover:bg-gray-100" phx-click="select_suggestion" phx-value-query={suggestion} phx-target={@myself}>
                <%= suggestion %>
              </div>
            <% end %>
          </div>
        <% end %>
      </form>
    </div>
    """
  end

  @impl true
  def update(assigns, socket) do
    {:ok,
     assign(socket,
       query: assigns[:query] || "",
       suggestions: [],
       debounce_time: @debounce_time,
       show_suggestions: false
     )}
  end

  @impl true
  def handle_event("suggest", %{"value" => query}, socket) when byte_size(query) >= 2 do
    case Search.suggest(query, @suggestion_limit) do
      {:ok, suggestions} ->
        {:noreply, assign(socket, suggestions: suggestions, show_suggestions: true, query: query)}
      {:error, _reason} ->
        {:noreply, assign(socket, suggestions: [], show_suggestions: false, query: query)}
    end
  end

  @impl true
  def handle_event("suggest", _params, socket) do
    {:noreply, assign(socket, suggestions: [], show_suggestions: false)}
  end

  @impl true
  def handle_event("hide_suggestions", _params, socket) do
    {:noreply, assign(socket, show_suggestions: false)}
  end

  @impl true
  def handle_event("search", %{"query" => query}, socket) do
    send(self(), {:search, query})
    {:noreply, assign(socket, query: query, show_suggestions: false)}
  end

  @impl true
  def handle_event("select_suggestion", %{"query" => query}, socket) do
    {:noreply, assign(socket, query: query, show_suggestions: false)}
  end
end

defmodule MoldbWeb.SearchLive do
  use MoldbWeb, :live_view
  alias Moldb.Search
  alias MoldbWeb.{SearchComponent, SearchResultsComponent}

  @per_page 20

  @impl true
  def mount(_params, _session, socket) do
    {:ok,
     assign(socket,
       results: [],
       query: "",
       page: 1,
       per_page: @per_page,
       filters: %{},
       loading: false,
       has_more: false
     )}
  end

  @impl true
  def render(assigns) do
    ~H"""
    <div class="max-w-2xl mx-auto p-6">
      <h1 class="text-3xl font-bold mb-6 text-center text-gray-800">Molecular Database Search</h1>

      <.live_component
        module={SearchComponent}
        id="search"
        query={@query}
      />

      <.live_component
        module={SearchResultsComponent}
        id="search_results"
        results={@results}
        has_more={@has_more}
        loading={@loading}
      />
    </div>
    """
  end

  @impl true
  def handle_info({:search, query}, socket) do
    # Reset pagination on new search
    socket = assign(socket, query: query, page: 1, results: [])
    {:noreply, load_more_results(socket, query, 1)}
  end

  @impl true
  def handle_event("load_more", _, socket) do
    %{query: query, page: page} = socket.assigns
    {:noreply, load_more_results(socket, query, page + 1)}
  end

  defp load_more_results(socket, query, page) do
    per_page = socket.assigns.per_page
    case Search.search(query, page, per_page, socket.assigns.filters) do
      {:ok, new_results} ->
        assign(socket,
          results: socket.assigns.results ++ new_results,
          page: page,
          has_more: length(new_results) == per_page,
          loading: false
        )
      {:error, _reason} ->
        put_flash(socket, :error, "Unable to load more results.")
        |> assign(loading: false)
    end
  end
end

defmodule Moldb.Search do
  import Ecto.Query
  alias Moldb.Repo
  alias Moldb.Compounds.{Compound, Substance}

  @type search_result :: %{
    type: String.t(),
    id: UUIDv7.t(),
    name: String.t(),
    description: String.t()
  }

  @spec search(String.t(), non_neg_integer(), pos_integer(), map()) :: {:ok, [search_result()]} | {:error, atom()}
  def search(query, page, per_page, filters) when is_binary(query) and is_integer(page) and is_integer(per_page) and is_map(filters) do
    with :ok <- Moldb.RateLimiter.check_rate_limit(),
         results <- perform_search(query, page, per_page, filters) do
      {:ok, results}
    else
      :error -> {:error, :rate_limit_exceeded}
    end
  end

  @spec suggest(String.t(), pos_integer()) :: {:ok, [String.t()]} | {:error, atom()}
  def suggest(query, limit) when is_binary(query) and is_integer(limit) do
    with :ok <- Moldb.RateLimiter.check_rate_limit(),
         suggestions <- perform_suggestions(query, limit) do
      {:ok, suggestions}
    else
      :error -> {:error, :rate_limit_exceeded}
    end
  end

  defp perform_search(query, page, per_page, filters) do
    offset = (page - 1) * per_page

    [
      search_query(Compound, :name, "compound", query, filters),
      search_query(Substance, :name, "substance", query, filters)
    ]
    |> Enum.flat_map(&Repo.all/1)
    |> Enum.sort_by(&rank(&1, query), :desc)
    |> Enum.slice(offset, per_page)
  end

  defp search_query(schema, field, type, query, filters) do
    from(s in schema,
      where: ilike(field(s, ^field), ^"%#{query}%"),
      where: ^build_filters(filters),
      order_by: fragment("SIMILARITY(?, ?) DESC", field(s, ^field), ^query),
      select: %{
        type: ^type,
        id: s.id,
        name: field(s, ^field),
        description: fragment("LEFT(?, 100)", s.description)
      }
    )
  end

  defp perform_suggestions(query, limit) do
    [
      suggestion_query(Compound, :name, query, limit),
      suggestion_query(Substance, :name, query, limit)
    ]
    |> Task.async_stream(&Repo.all/1, max_concurrency: 2, ordered: false)
    |> Enum.flat_map(fn {:ok, results} -> results end)
    |> Enum.uniq()
    |> Enum.sort_by(&String.jaro_distance(&1, query), :desc)
    |> Enum.take(limit)
  end

  defp suggestion_query(schema, field, query, limit) do
    from(s in schema,
      where: ilike(field(s, ^field), ^"#{query}%"),
      select: field(s, ^field),
      order_by: [asc: field(s, ^field)],
      limit: ^limit
    )
  end

  defp build_filters(filters) do
    Enum.reduce(filters, dynamic(true), fn
      {"status", status}, acc -> dynamic([s], ^acc and s.status == ^status)
      {"category", category}, acc -> dynamic([s], ^acc and s.category == ^category)
      _, acc -> acc
    end)
  end

  defp rank(%{type: type, name: name}, query) do
    base_score = type_score(type)
    String.jaro_distance(name, query) * base_score
  end

  defp type_score("compound"), do: 1.0
  defp type_score("substance"), do: 0.8
  defp type_score(_), do: 0.5
end


defmodule MoldbWeb.SearchResultsComponent do
  use MoldbWeb, :live_component

  def render(assigns) do
    ~H"""
    <div id="search-results" class="space-y-4 mt-8">
      <%= if Enum.empty?(@results) do %>
        <p class="text-center text-gray-600">No results found. Try a different search term.</p>
      <% else %>
        <%= for result <- @results do %>
          <div
            class="result bg-white p-4 rounded-lg shadow hover:shadow-md transition-shadow duration-200 ease-in-out cursor-pointer"
            phx-click="navigate"
            phx-value-id={result.id}
            phx-value-type={result.type}
          >
            <h3 class="text-lg font-semibold text-gray-800 mb-2"><%= result.name %></h3>
            <p class="text-sm text-gray-600"><%= result.description %></p>
            <span class="inline-block mt-2 px-2 py-1 text-xs font-semibold text-gray-700 bg-gray-200 rounded-full">
              <%= String.capitalize(result.type) %>
            </span>
          </div>
        <% end %>

        <%= if @has_more do %>
          <button
            phx-click="load_more"
            class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors"
            disabled={@loading}
          >
            <%= if @loading, do: "Loading...", else: "Load More" %>
          </button>
        <% end %>
      <% end %>
    </div>
    """
  end
end

defmodule MoldbWeb.PaginationComponent do
  use MoldbWeb, :live_component

  def render(assigns) do
    ~H"""
    <div class="mt-4 text-center">
      <%= if @loading do %>
        <p>Loading more results...</p>
      <% else %>
        <%= if @has_more do %>
          <button
            phx-click="load_more"
            class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors"
            disabled={@loading}
          >
            Load More
          </button>
        <% end %>
      <% end %>
    </div>
    """
  end
end

defmodule MoldbWeb.Router do
  use MoldbWeb, :router

  import MoldbWeb.UserAuth

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_live_flash
    plug :put_root_layout, html: {MoldbWeb.Layouts, :root}
    plug :protect_from_forgery
    plug :put_secure_browser_headers
    plug :fetch_current_user
  end

  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/", MoldbWeb do
    pipe_through :browser

    live "/", HomeLive, :index

    live "/search", SearchLive, :index
    live "/search/:query", SearchLive, :index

    live "/compounds", CompoundLive.Index, :index
    live "/compounds/new", CompoundLive.Index, :new
    live "/compound/:id/edit", CompoundLive.Index, :edit

    live "/compound/:id", CompoundLive.Show, :show
    live "/compound/:id/show/edit", CompoundLive.Show, :edit

    live "/substances", SubstanceLive.Index, :index
    live "/substances/new", SubstanceLive.Index, :new
    live "/substance/:id/edit", SubstanceLive.Index, :edit

    live "/substance/:id", SubstanceLive.Show, :show
    live "/substance/:id/show/edit", SubstanceLive.Show, :edit
  end

  # Other scopes may use custom stacks.
  # scope "/api", MoldbWeb do
  #   pipe_through :api
  # end

  # Enable LiveDashboard and Swoosh mailbox preview in development
  if Application.compile_env(:moldb, :dev_routes) do
    # If you want to use the LiveDashboard in production, you should put
    # it behind authentication and allow only admins to access it.
    # If your application does not have an admins-only section yet,
    # you can use Plug.BasicAuth to set up some basic authentication
    # as long as you are also using SSL (which you should anyway).
    import Phoenix.LiveDashboard.Router

    scope "/dev" do
      pipe_through :browser

      live_dashboard "/dashboard", metrics: MoldbWeb.Telemetry
      forward "/mailbox", Plug.Swoosh.MailboxPreview
    end
  end

  ## Authentication routes

  scope "/", MoldbWeb do
    pipe_through [:browser, :redirect_if_user_is_authenticated]

    live_session :redirect_if_user_is_authenticated,
      on_mount: [{MoldbWeb.UserAuth, :redirect_if_user_is_authenticated}] do
      live "/users/register", UserRegistrationLive, :new
      live "/users/log_in", UserLoginLive, :new
      live "/users/reset_password", UserForgotPasswordLive, :new
      live "/users/reset_password/:token", UserResetPasswordLive, :edit
    end

    post "/users/log_in", UserSessionController, :create
  end

  scope "/", MoldbWeb do
    pipe_through [:browser, :require_authenticated_user]

    live_session :require_authenticated_user,
      on_mount: [{MoldbWeb.UserAuth, :ensure_authenticated}] do
      live "/users/settings", UserSettingsLive, :edit
      live "/users/settings/confirm_email/:token", UserSettingsLive, :confirm_email
    end
  end

  scope "/", MoldbWeb do
    pipe_through [:browser]

    delete "/users/log_out", UserSessionController, :delete

    live_session :current_user,
      on_mount: [{MoldbWeb.UserAuth, :mount_current_user}] do
      live "/users/confirm/:token", UserConfirmationLive, :edit
      live "/users/confirm", UserConfirmationInstructionsLive, :new
    end
  end
end
Review and analyze this elixir phoenix framework code using liveview. Rewrite it to be highly efficient, high performance & scalable low latency, robust and modular system.