// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_WEBUI_NEW_TAB_PAGE_ACTION_CHIPS_ACTION_CHIPS_HANDLER_H_
#define CHROME_BROWSER_UI_WEBUI_NEW_TAB_PAGE_ACTION_CHIPS_ACTION_CHIPS_HANDLER_H_

#include <optional>
#include <vector>

#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/new_tab_page/action_chips/action_chips.mojom.h"
#include "chrome/browser/ui/webui/new_tab_page/action_chips/action_chips_generator.h"
#include "chrome/browser/ui/webui/new_tab_page/action_chips/tab_id_generator.h"
#include "chrome/browser/ui/webui/webui_embedding_context.h"
#include "components/omnibox/browser/searchbox.mojom.h"
#include "components/prefs/pref_change_registrar.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "url/gurl.h"

#if !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#endif

namespace base {
class TimeTicks;
}

namespace contextual_search {
class ContextualSearchSessionHandle;
}

class Profile;

class ActionChipsHandler : public action_chips::mojom::ActionChipsHandler
#if !BUILDFLAG(IS_ANDROID)
    ,
                           public TabStripModelObserver
#endif
{
 public:
  using GetSessionHandleCallback = base::RepeatingCallback<
      contextual_search::ContextualSearchSessionHandle*()>;

  ActionChipsHandler(
      mojo::PendingReceiver<action_chips::mojom::ActionChipsHandler> receiver,
      mojo::PendingRemote<action_chips::mojom::Page> page,
      Profile* profile,
      content::WebUI* web_ui,
      std::unique_ptr<ActionChipsGenerator> action_chips_generator,
      GetSessionHandleCallback get_session_handle_callback);
  ActionChipsHandler(const ActionChipsHandler&) = delete;
  ActionChipsHandler& operator=(const ActionChipsHandler&) = delete;
  ~ActionChipsHandler() override;

  // action_chips::mojom::ActionChipsHandler:
  void StartActionChipsRetrieval() override;
  void ActivateMetricsFunnel(const std::string& funnel_name) override;
  void SetActionChipsVisibility(bool is_visible) override;
  void NavigateToAim(const std::string& query_text,
                     uint8_t mouse_button,
                     searchbox::mojom::ActionModifiersPtr modifiers) override;

#if !BUILDFLAG(IS_ANDROID)
  void OnTabStripModelChanged(
      TabStripModel* tab_strip_model,
      const TabStripModelChange& change,
      const TabStripSelectionChange& selection) override;
#endif

 private:
  void SendActionChipsToUi(
      base::TimeTicks start_time,
      std::vector<action_chips::mojom::ActionChipPtr> chips);

  // Returns true if chips retrieval should not occur in the current call.
  // This method was introduced to address the issue of jittering experience
  // when the user switches among multiple NTPs without a change in the most
  // recent tab.
  bool ShouldThrottleRetrieval(const GURL& current_url);
  void OnVisibilityChanged();

  mojo::Receiver<action_chips::mojom::ActionChipsHandler> receiver_;
  mojo::Remote<action_chips::mojom::Page> page_;
  raw_ptr<Profile> profile_;
  raw_ptr<content::WebUI> web_ui_;
  std::unique_ptr<ActionChipsGenerator> action_chips_generator_;
  GetSessionHandleCallback get_session_handle_callback_;
  PrefChangeRegistrar pref_change_registrar_;

  std::optional<GURL> last_processed_url_;
  bool has_recorded_any_shown_ = false;

  base::WeakPtrFactory<ActionChipsHandler> weak_factory_{this};
};

#endif  // CHROME_BROWSER_UI_WEBUI_NEW_TAB_PAGE_ACTION_CHIPS_ACTION_CHIPS_HANDLER_H_
