// 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 COMPONENTS_FACILITATED_PAYMENTS_CORE_BROWSER_PIX_ACCOUNT_LINKING_MANAGER_H_
#define COMPONENTS_FACILITATED_PAYMENTS_CORE_BROWSER_PIX_ACCOUNT_LINKING_MANAGER_H_

#include <vector>

#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "components/autofill/core/browser/payments/payments_autofill_client.h"
#include "components/facilitated_payments/core/browser/native_account_linking_handler.h"
#include "components/facilitated_payments/core/browser/network_api/facilitated_payments_network_interface.h"
#include "components/facilitated_payments/core/browser/strike_databases/pix_account_linking_strike_database.h"
#include "components/facilitated_payments/core/utils/facilitated_payments_ui_utils.h"
#include "url/origin.h"

namespace payments::facilitated {

class FacilitatedPaymentsClient;
// A cross-platform interface that manages the Pix account linking flow. It is
// owned by `FacilitatedPaymentsClient`. There is 1 instance of this class per
// tab. Its lifecycle is same as that of `FacilitatedPaymentsClient`.

// The Pix account linking prompt is shown after the user has paid on their bank
// app and returned to Chrome. Some merchants show the order status causing page
// navigations. To overcome such cases, the manager should be associated with
// the tab, and not a single frame.
class PixAccountLinkingManager : public NativeAccountLinkingHandler {
 public:
  explicit PixAccountLinkingManager(
      FacilitatedPaymentsClient* client,
      FacilitatedPaymentsApiClientCreator api_client_creator =
          FacilitatedPaymentsApiClientCreator());
  ~PixAccountLinkingManager() override;

  // Initialize the Pix account linking flow. Virtual so it can be overridden in
  // tests.
  virtual void MaybeShowPixAccountLinkingPrompt(
      const url::Origin& pix_payment_page_origin);

 protected:
  std::optional<AccountLinkingParams> CreateAccountLinkingParams() override;
  // NativeAccountLinkingHandler:
  std::string_view GetHistogramSuffix() const override;
  strike_database::StrikeDatabaseIntegratorBase* GetStrikeDatabase() override;
  bool IsUserPrefEnabled() const override;
  base::DictValue GetPayloadForGetDetailsForCreatePaymentInstrument() override;
  void DoOnClientTokenReceived(
      const std::vector<uint8_t>& client_token) override;
  void DoOnGetDetailsForCreatePaymentInstrumentResponse(
      bool is_eligible) override;
  void DoOnAccepted() override;
  void DoOnAccountLinkingResult(AccountLinkingResult result) override;
  base::WeakPtr<NativeAccountLinkingHandler> GetWeakPtr() override;

 private:
  friend class PixAccountLinkingManagerTestApi;

  void Reset();

  // Called when the user returns to Chrome after paying in bank app.
  void OnUserReturnedToChrome();

  // Called after the predefined wait time following user return to Chrome.
  void OnPostReturnDelayPassed();

  // Sets the UI event listener, sets the internal UI state, and triggers
  // showing the Pix account linking prompt if the user is eligible.
  void ShowPixAccountLinkingPromptIfEligible();

  // Shows the Pix account linking prompt to user after the predefined wait
  // time.
  void ShowPixAccountLinkingPromptAfterDelay();

  // Called by the view to communicate UI events.
  void OnUiScreenEvent(UiEvent ui_event_type);

  // Stores the client token received from FetchClientToken().
  std::vector<uint8_t> client_token_;

  // Track if the user has returned to Chrome tab from the bank app.
  bool has_user_returned_to_chrome_ = false;

  // Track if the delay after returning to Chrome has elapsed.
  bool has_post_return_delay_passed_ = false;

  // Optional bool to indicate whether the user is eligible for Pix account
  // linking based on the response from payments backend. This field is set to
  // optional to be able to differentiate between the case where the server
  // response is not received yet.
  std::optional<bool> is_eligible_for_pix_account_linking_ = std::nullopt;

  // The origin of the Pix payment page that triggered the account linking flow.
  url::Origin pix_payment_page_origin_;

  // Set to true when the user accepts the prompt to differentiate between
  // prompt decline and GMSCore flow cancellation.
  bool is_prompt_accepted_ = false;

  // Returns the strike database for Pix account linking, creating it if needed.
  PixAccountLinkingStrikeDatabase* GetOrCreateStrikeDatabase();

  // Strike database to enforce strike limits and cool-off periods.
  std::unique_ptr<PixAccountLinkingStrikeDatabase> strike_database_;

  base::WeakPtrFactory<PixAccountLinkingManager> weak_ptr_factory_{this};
};

}  // namespace payments::facilitated

#endif  // COMPONENTS_FACILITATED_PAYMENTS_CORE_BROWSER_PIX_ACCOUNT_LINKING_MANAGER_H_
