package uiapi

import (
	"testing"

	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
)

// =============================================================================
// Navigation item filtering logic (used by RemoveObjectFromAllAppsTx)
//
// We can't easily test RemoveObjectFromAllAppsTx itself without mocking
// MetadataService.GetApps and UpdateAppTx, but we can test the core filtering
// logic that determines which items to keep/remove.
// =============================================================================

func TestFilterNavigationItems_RemovesTargetObject(t *testing.T) {
	objectToRemove := "CustomObject__c"
	items := []models.NavigationItem{
		{ID: "nav-1", Type: constants.NavigationTypeObject, ObjectAPIName: "Account"},
		{ID: "nav-2", Type: constants.NavigationTypeObject, ObjectAPIName: objectToRemove},
		{ID: "nav-3", Type: constants.NavigationTypeObject, ObjectAPIName: "Contact"},
		{ID: "nav-4", Type: "page", ObjectAPIName: "SomePage"},
	}

	// Replicate the filtering logic from RemoveObjectFromAllAppsTx
	var filtered []models.NavigationItem
	updated := false
	for _, item := range items {
		if item.Type == constants.NavigationTypeObject && item.ObjectAPIName == objectToRemove {
			updated = true
			continue
		}
		filtered = append(filtered, item)
	}

	if !updated {
		t.Error("expected updated to be true")
	}
	if len(filtered) != 3 {
		t.Fatalf("expected 3 items after filtering, got %d", len(filtered))
	}

	// Verify the correct items remain
	for _, item := range filtered {
		if item.ObjectAPIName == objectToRemove && item.Type == constants.NavigationTypeObject {
			t.Error("target object should have been removed")
		}
	}
}

func TestFilterNavigationItems_NoMatch(t *testing.T) {
	items := []models.NavigationItem{
		{ID: "nav-1", Type: constants.NavigationTypeObject, ObjectAPIName: "Account"},
		{ID: "nav-2", Type: constants.NavigationTypeObject, ObjectAPIName: "Contact"},
	}

	var filtered []models.NavigationItem
	updated := false
	for _, item := range items {
		if item.Type == constants.NavigationTypeObject && item.ObjectAPIName == "NonExistent" {
			updated = true
			continue
		}
		filtered = append(filtered, item)
	}

	if updated {
		t.Error("expected updated to be false when object not found")
	}
	if len(filtered) != 2 {
		t.Errorf("expected 2 items, got %d", len(filtered))
	}
}

func TestFilterNavigationItems_KeepsNonObjectTypes(t *testing.T) {
	// Even if ObjectAPIName matches, non-object type items should be kept
	items := []models.NavigationItem{
		{ID: "nav-1", Type: "page", ObjectAPIName: "TargetObject"},
		{ID: "nav-2", Type: "web", ObjectAPIName: "TargetObject"},
		{ID: "nav-3", Type: "dashboard", ObjectAPIName: "TargetObject"},
	}

	var filtered []models.NavigationItem
	updated := false
	for _, item := range items {
		if item.Type == constants.NavigationTypeObject && item.ObjectAPIName == "TargetObject" {
			updated = true
			continue
		}
		filtered = append(filtered, item)
	}

	if updated {
		t.Error("expected updated to be false for non-object type items")
	}
	if len(filtered) != 3 {
		t.Errorf("expected all 3 items kept, got %d", len(filtered))
	}
}

func TestFilterNavigationItems_EmptyItems(t *testing.T) {
	var items []models.NavigationItem

	var filtered []models.NavigationItem
	updated := false
	for _, item := range items {
		if item.Type == constants.NavigationTypeObject && item.ObjectAPIName == "Anything" {
			updated = true
			continue
		}
		filtered = append(filtered, item)
	}

	if updated {
		t.Error("expected updated to be false for empty items")
	}
	if len(filtered) != 0 {
		t.Errorf("expected 0 items, got %d", len(filtered))
	}
}

func TestFilterNavigationItems_MultipleMatchesRemoved(t *testing.T) {
	// If an object appears in nav items multiple times, all instances should be removed
	target := "DuplicateObject__c"
	items := []models.NavigationItem{
		{ID: "nav-1", Type: constants.NavigationTypeObject, ObjectAPIName: target},
		{ID: "nav-2", Type: constants.NavigationTypeObject, ObjectAPIName: "Account"},
		{ID: "nav-3", Type: constants.NavigationTypeObject, ObjectAPIName: target},
	}

	var filtered []models.NavigationItem
	removeCount := 0
	for _, item := range items {
		if item.Type == constants.NavigationTypeObject && item.ObjectAPIName == target {
			removeCount++
			continue
		}
		filtered = append(filtered, item)
	}

	if removeCount != 2 {
		t.Errorf("expected 2 removals, got %d", removeCount)
	}
	if len(filtered) != 1 {
		t.Errorf("expected 1 item remaining, got %d", len(filtered))
	}
	if filtered[0].ObjectAPIName != "Account" {
		t.Errorf("expected Account to remain, got %q", filtered[0].ObjectAPIName)
	}
}

// =============================================================================
// Navigation item creation (used by CreateObjectWithApp)
// =============================================================================

func TestNavigationItem_Construction(t *testing.T) {
	item := models.NavigationItem{
		ID:            "nav-test-123",
		Type:          constants.NavigationTypeObject,
		ObjectAPIName: "MyObject__c",
		Label:         "My Objects",
		Icon:          "custom:custom1",
	}

	if item.Type != "object" {
		t.Errorf("Type = %q, want 'object'", item.Type)
	}
	if item.ObjectAPIName != "MyObject__c" {
		t.Errorf("ObjectAPIName = %q, want 'MyObject__c'", item.ObjectAPIName)
	}
	if item.Label != "My Objects" {
		t.Errorf("Label = %q, want 'My Objects'", item.Label)
	}
}
