package rest

import (
	"testing"

	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestEnrichNavLabels_UsesSchemaLookup(t *testing.T) {
	schemas := []*models.ObjectMetadata{
		{APIName: "Account", Label: "Account", PluralLabel: "Accounts"},
		{APIName: "Campaign", Label: "Campaign", PluralLabel: "Campaigns"},
		{APIName: "Lead", Label: "Lead", PluralLabel: "Leads"},
		{APIName: "PoC__c", Label: "POC", PluralLabel: "POCs"},
		{APIName: "Invoice_Collection__c", Label: "Invoice Collection", PluralLabel: "Invoice Collections"},
	}

	app := &models.AppConfig{
		ID:    "test_app",
		Label: "Test",
		NavigationItems: []models.NavigationItem{
			{ID: "n1", Type: constants.NavigationTypeObject, ObjectAPIName: "Account", Label: "Account"},
			{ID: "n2", Type: constants.NavigationTypeObject, ObjectAPIName: "campaign", Label: "campaign"},
			{ID: "n3", Type: constants.NavigationTypeObject, ObjectAPIName: "lead", Label: "lead"},
			{ID: "n4", Type: constants.NavigationTypeObject, ObjectAPIName: "PoC__c", Label: "poc__c"},
			{ID: "n5", Type: constants.NavigationTypeObject, ObjectAPIName: "Invoice_Collection__c", Label: "invoice_collection__c"},
			{ID: "n6", Type: constants.NavigationTypePage, Label: "Home"},
		},
	}

	enrichNavLabelsFromSchemas(app, schemas)

	require.Len(t, app.NavigationItems, 6)
	assert.Equal(t, "Accounts", app.NavigationItems[0].Label)
	assert.Equal(t, "Campaigns", app.NavigationItems[1].Label)
	assert.Equal(t, "Leads", app.NavigationItems[2].Label)
	assert.Equal(t, "POCs", app.NavigationItems[3].Label)
	assert.Equal(t, "Invoice Collections", app.NavigationItems[4].Label)
	assert.Equal(t, "Home", app.NavigationItems[5].Label, "non-object items should keep original label")
}

func TestEnrichNavLabels_FallsBackToLabel(t *testing.T) {
	schemas := []*models.ObjectMetadata{
		{APIName: "Account", Label: "Account", PluralLabel: ""},
	}

	app := &models.AppConfig{
		ID:    "test_app",
		Label: "Test",
		NavigationItems: []models.NavigationItem{
			{ID: "n1", Type: constants.NavigationTypeObject, ObjectAPIName: "Account", Label: "account"},
		},
	}

	enrichNavLabelsFromSchemas(app, schemas)

	assert.Equal(t, "Account", app.NavigationItems[0].Label, "should fallback to schema.Label when PluralLabel is empty")
}

func TestEnrichNavLabels_SchemaNotFound_KeepsOriginal(t *testing.T) {
	schemas := []*models.ObjectMetadata{}

	app := &models.AppConfig{
		ID:    "test_app",
		Label: "Test",
		NavigationItems: []models.NavigationItem{
			{ID: "n1", Type: constants.NavigationTypeObject, ObjectAPIName: "Unknown__c", Label: "unknown__c"},
		},
	}

	enrichNavLabelsFromSchemas(app, schemas)

	assert.Equal(t, "unknown__c", app.NavigationItems[0].Label, "should keep original when schema not found")
}

func TestEnrichNavLabels_EmptyNavItems(t *testing.T) {
	schemas := []*models.ObjectMetadata{
		{APIName: "Account", PluralLabel: "Accounts"},
	}

	app := &models.AppConfig{
		ID:    "test_app",
		Label: "Test",
	}

	enrichNavLabelsFromSchemas(app, schemas)
	assert.Nil(t, app.NavigationItems)
}

func TestToAppConfig_StandardObjectLabelsAreRawAPINames(t *testing.T) {
	req := &toolingCustomApplicationRequest{
		FullName: "test_app",
		Metadata: toolingCustomApplicationMetadata{
			Label: "Test",
			Tabs:  []string{"standard-campaign", "standard-lead", "PoC__c", "Invoice_Collection__c"},
		},
	}

	app := req.toAppConfig()

	require.Len(t, app.NavigationItems, 4)
	assert.Equal(t, "campaign", app.NavigationItems[0].Label,
		"before enrichment, standard object labels are raw API names")
	assert.Equal(t, "lead", app.NavigationItems[1].Label)
	assert.Equal(t, "PoC__c", app.NavigationItems[2].ObjectAPIName)
	assert.Equal(t, "Invoice_Collection__c", app.NavigationItems[3].ObjectAPIName)
}
