// Copyright 2026 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/webui/indigo_internals/indigo_internals_page_handler.h"

#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "chrome/browser/indigo/indigo_service.h"
#include "chrome/browser/indigo/indigo_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/skills/skills_service_factory.h"
#include "chrome/common/chrome_features.h"
#include "components/optimization_guide/core/optimization_guide_features.h"
#include "components/optimization_guide/core/optimization_guide_permissions_util.h"
#include "components/skills/public/skill.h"
#include "components/skills/public/skills_service.h"

namespace {

indigo_internals::mojom::LocalEligibility MapLocalEligibility(
    indigo::LocalEligibility status) {
  switch (status) {
    case indigo::LocalEligibility::kEligible:
      return indigo_internals::mojom::LocalEligibility::kEligible;
    case indigo::LocalEligibility::kNotSignedIn:
      return indigo_internals::mojom::LocalEligibility::kNotSignedIn;
    case indigo::LocalEligibility::kRefreshTokenInPersistentErrorState:
      return indigo_internals::mojom::LocalEligibility::
          kRefreshTokenInPersistentErrorState;
    case indigo::LocalEligibility::kMissingCapabilities:
      return indigo_internals::mojom::LocalEligibility::kMissingCapabilities;
    case indigo::LocalEligibility::kDisabledByPolicy:
      return indigo_internals::mojom::LocalEligibility::kDisabledByPolicy;
    case indigo::LocalEligibility::kMissingScript:
      return indigo_internals::mojom::LocalEligibility::kMissingScript;
    case indigo::LocalEligibility::kManagedDomain:
      return indigo_internals::mojom::LocalEligibility::kManagedDomain;
    case indigo::LocalEligibility::kGlicDisabledForProfile:
      return indigo_internals::mojom::LocalEligibility::kGlicDisabledForProfile;
    case indigo::LocalEligibility::kEnterpriseDisallowed:
      return indigo_internals::mojom::LocalEligibility::kEnterpriseDisallowed;
  }
}

indigo_internals::mojom::OptimizationGuideStatus
GetCurrentOptimizationGuideStatus(Profile* profile) {
  if (!optimization_guide::features::IsOptimizationHintsEnabled()) {
    return indigo_internals::mojom::OptimizationGuideStatus::kDisabled;
  }
  if (!optimization_guide::IsUserPermittedToFetchFromRemoteOptimizationGuide(
          profile->IsOffTheRecord(), profile->GetPrefs())) {
    return indigo_internals::mojom::OptimizationGuideStatus::kNotPermitted;
  }
  return indigo_internals::mojom::OptimizationGuideStatus::kEnabled;
}

}  // namespace

IndigoInternalsPageHandler::IndigoInternalsPageHandler(
    mojo::PendingReceiver<indigo_internals::mojom::PageHandler> receiver,
    mojo::PendingRemote<indigo_internals::mojom::Page> page,
    Profile* profile)
    : receiver_(this, std::move(receiver)),
      page_(std::move(page)),
      profile_(profile),
      consent_helper_(
          unified_consent::UrlKeyedDataCollectionConsentHelper::
              NewAnonymizedDataCollectionConsentHelper(profile->GetPrefs())) {
  indigo::IndigoService* service =
      indigo::IndigoServiceFactory::GetForProfile(profile_);
  CHECK(service);
  subscription_ =
      service->RegisterLocalEligibilityChangedCallback(base::BindRepeating(
          &IndigoInternalsPageHandler::OnLocalEligibilityChanged,
          base::Unretained(this)));
  consent_observation_.Observe(consent_helper_.get());
}

IndigoInternalsPageHandler::~IndigoInternalsPageHandler() = default;

void IndigoInternalsPageHandler::GetLocalEligibility(
    GetLocalEligibilityCallback callback) {
  indigo::IndigoService* service =
      indigo::IndigoServiceFactory::GetForProfile(profile_);
  CHECK(service);

  std::move(callback).Run(MapLocalEligibility(service->GetLocalEligibility()));
}

void IndigoInternalsPageHandler::OnLocalEligibilityChanged(
    indigo::LocalEligibility status) {
  page_->OnLocalEligibilityChanged(MapLocalEligibility(status));
}

void IndigoInternalsPageHandler::GetCombinedEligibility(
    GetCombinedEligibilityCallback callback) {
  indigo::IndigoService* service =
      indigo::IndigoServiceFactory::GetForProfile(profile_);
  CHECK(service);

  service->GetCombinedEligibility(base::BindOnce(
      [](GetCombinedEligibilityCallback callback,
         const indigo::CombinedEligibility& eligibility) {
        auto mojo_eligibility =
            indigo_internals::mojom::CombinedEligibility::New();
        mojo_eligibility->local_eligibility =
            MapLocalEligibility(eligibility.local_eligibility);

        if (eligibility.remote_eligibility.has_value()) {
          auto remote_mojo = indigo_internals::mojom::RemoteEligibility::New();
          remote_mojo->is_service_supported_for_account =
              eligibility.remote_eligibility->is_service_supported_for_account;
          remote_mojo->has_user_image =
              eligibility.remote_eligibility->has_user_image;
          mojo_eligibility->remote_eligibility = std::move(remote_mojo);
        }

        mojo_eligibility->can_generate_image = eligibility.CanGenerateImage();
        mojo_eligibility->ready_to_onboard = eligibility.ReadyToOnboard();
        mojo_eligibility->has_onboarded_pref = eligibility.has_onboarded_pref;
        std::move(callback).Run(std::move(mojo_eligibility));
      },
      std::move(callback)));
}

void IndigoInternalsPageHandler::GetOptimizationGuideStatus(
    GetOptimizationGuideStatusCallback callback) {
  std::move(callback).Run(GetCurrentOptimizationGuideStatus(profile_));
}

void IndigoInternalsPageHandler::GetGlicPromptInfo(
    GetGlicPromptInfoCallback callback) {
  auto info = indigo_internals::mojom::GlicPromptInfo::New();
  info->integration_enabled =
      base::FeatureList::IsEnabled(features::kIndigoOpenGlic);
  info->current_key = features::kIndigoGlicPromptKey.Get();
  info->override_prompt = features::kIndigoGlicPrompt.Get();

  info->skill_id = features::kIndigoGlicSkillId.Get();
  if (!info->skill_id.empty()) {
    if (auto* skills_service =
            skills::SkillsServiceFactory::GetForProfile(profile_)) {
      if (const skills::Skill* skill =
              skills_service->GetSkillById(info->skill_id)) {
        info->skill_name = skill->name;
      }
    }
  }

  indigo::IndigoService* service =
      indigo::IndigoServiceFactory::GetForProfile(profile_);
  if (service) {
    for (const auto& [key, prompt] : service->GetLoadedPrompts()) {
      auto mojo_prompt = indigo_internals::mojom::IndigoPrompt::New();
      mojo_prompt->key = key;
      mojo_prompt->prompt = prompt;
      info->loaded_prompts.push_back(std::move(mojo_prompt));
    }
  }
  std::move(callback).Run(std::move(info));
}

void IndigoInternalsPageHandler::OnUrlKeyedDataCollectionConsentStateChanged(
    unified_consent::UrlKeyedDataCollectionConsentHelper* consent_helper) {
  page_->OnOptimizationGuideStatusChanged(
      GetCurrentOptimizationGuideStatus(profile_));
}
