// 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 "components/browser_apis/tab_strip/testing/toy_tab_strip_model_adapter.h"

#include <utility>

#include "base/notimplemented.h"
#include "base/strings/string_number_conversions.h"
#include "components/browser_apis/tab_strip/types/tab_states.h"

namespace tabs_api::testing {

ToyTabStripModelAdapter::ToyTabStripModelAdapter(ToyTabStrip* tab_strip)
    : tab_strip_(tab_strip) {}

std::vector<tabs::TabHandle> ToyTabStripModelAdapter::GetTabs() const {
  return tab_strip_->GetTabs();
}

tabs_api::types::TabStates ToyTabStripModelAdapter::GetTabStates(
    tabs::TabHandle handle) const {
  return {
      .is_active = tab_strip_->GetToyTabFor(handle)->active,
      .is_selected = tab_strip_->GetToyTabFor(handle)->selected,
  };
}

const ui::ColorProvider& ToyTabStripModelAdapter::GetColorProvider() const {
  return color_provider_;
}

void ToyTabStripModelAdapter::CloseTab(size_t idx) {
  tab_strip_->CloseTab(idx);
}

void ToyTabStripModelAdapter::CloseTabGroup(
    const tab_groups::TabGroupId& group_id) {
  tab_strip_->CloseTabGroup(group_id);
}

std::optional<int> ToyTabStripModelAdapter::GetIndexForHandle(
    tabs::TabHandle tab_handle) const {
  return tab_strip_->GetIndexForHandle(tab_handle);
}

void ToyTabStripModelAdapter::ActivateTab(size_t idx) {
  const auto tab = tab_strip_->GetTabs().at(idx);
  tab_strip_->ActivateTab(tab);
}

base::expected<void, mojo_base::mojom::ErrorPtr>
ToyTabStripModelAdapter::MoveTab(tabs::TabHandle handle,
                                 const Position& position) {
  tab_strip_->MoveTab(handle, position.index());
  return base::ok();
}

base::expected<void, mojo_base::mojom::ErrorPtr>
ToyTabStripModelAdapter::MoveCollection(const NodeId& id,
                                        const Position& position) {
  // TODO(crbug.com/412709271): Integrate with the toy tabstrip to move a
  // collection.
  NOTIMPLEMENTED();
  return base::ok();
}

mojom::ContainerPtr ToyTabStripModelAdapter::GetTabStripTopology(
    tabs::TabCollection::Handle root) const {
  auto mojo_tab_strip = tabs_api::mojom::TabStrip::New();
  mojo_tab_strip->id =
      tabs_api::NodeId(tabs_api::NodeId::Type::kCollection, "0");

  auto window_container = tabs_api::mojom::Container::New();
  auto window_data = tabs_api::mojom::Window::New();
  window_data->id = tabs_api::NodeId(tabs_api::NodeId::Type::kWindow, "1");
  window_container->data =
      tabs_api::mojom::Data::NewWindow(std::move(window_data));

  auto tab_strip_container = tabs_api::mojom::Container::New();
  tab_strip_container->data =
      tabs_api::mojom::Data::NewTabStrip(std::move(mojo_tab_strip));

  std::vector<tabs::TabHandle> tabs = tab_strip_->GetTabs();
  for (auto& handle : tabs) {
    auto tab = tabs_api::mojom::Tab::New();
    tab->id = tabs_api::NodeId(tabs_api::NodeId::Type::kContent,
                               base::NumberToString(handle.raw_value()));
    auto child_container = tabs_api::mojom::Container::New();
    child_container->data = tabs_api::mojom::Data::NewTab(std::move(tab));
    tab_strip_container->children.push_back(std::move(child_container));
  }
  window_container->children.push_back(std::move(tab_strip_container));
  return window_container;
}

std::optional<const tab_groups::TabGroupId>
ToyTabStripModelAdapter::FindGroupIdFor(
    const tabs::TabCollection::Handle& collection_handle) const {
  return tab_strip_->GetGroupIdFor(collection_handle);
}

void ToyTabStripModelAdapter::UpdateTabGroupVisuals(
    const tab_groups::TabGroupId& group,
    const tab_groups::TabGroupVisualData& visual_data) {
  tab_strip_->UpdateGroupVisuals(group, visual_data);
}

void ToyTabStripModelAdapter::SetTabSelection(
    const std::vector<tabs::TabHandle>& handles_to_select,
    tabs::TabHandle to_activate) {
  std::set<tabs::TabHandle> selection(handles_to_select.begin(),
                                      handles_to_select.end());
  tab_strip_->SetTabSelection(selection);
  tab_strip_->SetActiveTab(to_activate);
}

std::optional<tab_groups::TabGroupId>
ToyTabStripModelAdapter::GetTabGroupForTab(int index) const {
  return tab_strip_->GetTabGroupForTab(index);
}

tabs::TabCollectionHandle
ToyTabStripModelAdapter::GetCollectionHandleForTabGroupId(
    tab_groups::TabGroupId group_id) const {
  return tab_strip_->GetCollectionHandleForTabGroupId(group_id);
}

tabs::TabCollectionHandle
ToyTabStripModelAdapter::GetCollectionHandleForSplitTabId(
    split_tabs::SplitTabId split_id) const {
  return tab_strip_->GetCollectionHandleForSplitTabId(split_id);
}

tabs_api::Position ToyTabStripModelAdapter::GetPositionForAbsoluteIndex(
    int absolute_index) const {
  NOTIMPLEMENTED();
  return tabs_api::Position(0);
}

tabs_api::Path ToyTabStripModelAdapter::GetPathForCollection(
    tabs::TabCollectionHandle collection_handle) const {
  std::vector<tabs_api::NodeId> components;
  components.emplace_back(tabs_api::NodeId::Type::kWindow, "1");
  components.emplace_back(NodeId::FromTabCollectionHandle(collection_handle));
  return tabs_api::Path(std::move(components));
}

InsertionParams ToyTabStripModelAdapter::CalculateInsertionParams(
    const std::optional<tabs_api::Position>& pos) const {
  NOTIMPLEMENTED();
  return tabs_api::InsertionParams();
}

base::expected<void, mojo_base::mojom::ErrorPtr>
ToyTabStripModelAdapter::ReplaceTabInSplit(tabs::TabHandle tab_to_replace,
                                           int tab_to_insert_index) {
  NOTIMPLEMENTED();
  return base::ok();
}

const tabs::TabCollection* ToyTabStripModelAdapter::GetRoot() const {
  return tab_strip_->GetRoot().Get();
}

}  // namespace tabs_api::testing
