// 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.

#include "chrome/browser/ui/views/translate/translate_page_action_controller.h"

#include "base/check_deref.h"
#include "base/functional/bind.h"
#include "chrome/browser/translate/chrome_translate_client.h"
#include "chrome/browser/ui/actions/chrome_action_id.h"
#include "chrome/browser/ui/browser_actions.h"
#include "chrome/browser/ui/browser_window/public/browser_window_features.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
#include "chrome/browser/ui/page_action/page_action_controller.h"
#include "chrome/browser/ui/page_action/page_action_icon_type.h"
#include "chrome/browser/ui/tabs/public/tab_features.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/translate/translate_bubble_controller.h"
#include "components/tabs/public/tab_interface.h"
#include "components/translate/core/browser/language_state.h"
#include "components/translate/core/browser/translate_manager.h"
#include "ui/actions/actions.h"
#include "ui/base/ui_base_features.h"

namespace {
ChromeTranslateClient& GetTranslateClient(
    const tabs::TabInterface& tab_interface) {
  ChromeTranslateClient* client =
      ChromeTranslateClient::FromWebContents(tab_interface.GetContents());
  CHECK(client);
  return *client;
}
}  // namespace

TranslatePageActionController::TranslatePageActionController(
    tabs::TabInterface& tab_interface)
    : PageActionObserver(kActionShowTranslate), tab_interface_(tab_interface) {
  translate_observation_.Observe(
      GetTranslateClient(tab_interface).translate_driver());
  will_discard_contents_subscription_ =
      tab_interface_->RegisterWillDiscardContents(base::BindRepeating(
          &TranslatePageActionController::WillDiscardContents,
          base::Unretained(this)));

  RegisterAsPageActionObserver(
      CHECK_DEREF(tab_interface_->GetTabFeatures()->page_action_controller()));

  // Translation may be enabled already at the time of creating the tab (e.g.,
  // while moving contents from a browser windows to a web app).
  UpdatePageAction();
}

TranslatePageActionController::~TranslatePageActionController() = default;

void TranslatePageActionController::OnPageActionIconShown(
    const page_actions::PageActionState& page_action) {
  RecordIconChange(true);
}

void TranslatePageActionController::OnPageActionIconHidden(
    const page_actions::PageActionState& page_action) {
  RecordIconChange(false);
}

void TranslatePageActionController::OnTranslateEnabledChanged(
    content::WebContents* source) {
  UpdatePageAction();
}

void TranslatePageActionController::RecordIconChange(bool is_showing) {
  GetTranslateClient(tab_interface_.get())
      .GetTranslateManager()
      ->GetActiveTranslateMetricsLogger()
      ->LogOmniboxIconChange(is_showing);
}

void TranslatePageActionController::WillDiscardContents(
    tabs::TabInterface* tab_interface,
    content::WebContents* old_contents,
    content::WebContents* new_contents) {
  translate_observation_.Reset();
  translate_observation_.Observe(
      ChromeTranslateClient::FromWebContents(new_contents)->translate_driver());
}

void TranslatePageActionController::UpdatePageAction() {
  if (!tab_interface_->GetContents()) {
    return;
  }

  ChromeTranslateClient& translate_client =
      GetTranslateClient(tab_interface_.get());
  const translate::LanguageState& language_state =
      translate_client.GetLanguageState();
  const bool translate_enabled = language_state.translate_enabled();

  page_actions::PageActionController* page_action_controller =
      tab_interface_->GetTabFeatures()->page_action_controller();
  CHECK(page_action_controller);

  if (translate_enabled) {
    // TODO(crbug.com/404190582): Currently, the translate manager doesn't
    // update the action synchronously, and waits on tab state changes for
    // updates instead, making it possible the action to be out of sync. If
    // translation is enabled, then we should be ok to show the translate  UI,
    // so we manually enable the action here. This should be removed once the
    // bug is fixed.
    actions::ActionManager::Get()
        .FindAction(
            kActionShowTranslate,
            BrowserActions::From(tab_interface_->GetBrowserWindowInterface())
                ->root_action_item())
        ->SetEnabled(true);
    page_action_controller->Show(kActionShowTranslate);
  } else {
    page_action_controller->Hide(kActionShowTranslate);
    if (TranslateBubbleController* bubble_controller =
            TranslateBubbleController::From(
                tab_interface_->GetBrowserWindowInterface())) {
      bubble_controller->CloseBubble();
    }
  }
}
