//go:build integration

package uiapi

import (
	"context"
	"fmt"
	"testing"
	"time"

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

func TestUIAPI_CreateObjectWithApp_Integration(t *testing.T) {
	_, ms, _, svc := SetupIntegrationTest(t)
	// db := conn.DB()

	t.Run("Create Object Adds to App Navigation", func(t *testing.T) {
		ctx := context.Background()
		uniqueID := time.Now().UnixNano()

		// 1. Create a Test App
		appID := fmt.Sprintf("app_uiapi_%d", uniqueID)
		app := &models.AppConfig{
			ID:              appID,
			Label:           "UIAPI Test App",
			NavigationItems: []models.NavigationItem{},
		}
		require.NoError(t, ms.CreateApp(ctx, app))
		defer func() { _ = ms.DeleteApp(ctx, appID) }()

		// 2. Define Object Schema
		objName := fmt.Sprintf("uiapi_obj_%d", uniqueID)
		schema := &models.ObjectMetadata{
			ID:          fmt.Sprintf("obj_%d", uniqueID),
			APIName:     objName,
			PluralLabel: "UIAPI Objects",
			Label:       "UIAPI Object",
			Icon:        "action:bug",
		}
		// Clean up object after test
		defer func() { _ = ms.DeleteSchema(ctx, objName) }() // Metadata service delete

		// 3. Call CreateObjectWithApp (The method under test)
		err := svc.CreateObjectWithApp(ctx, appID, schema)
		require.NoError(t, err)

		// 4. Verify Object Created
		createdSchema := ms.GetSchema(ctx, objName)
		require.NotNil(t, createdSchema)
		assert.Equal(t, appID, *createdSchema.AppID)

		// 5. Verify App Navigation Updated
		updatedApp := ms.GetApp(ctx, appID)
		require.NotNil(t, updatedApp)
		require.Len(t, updatedApp.NavigationItems, 1, "Should have 1 nav item")

		navItem := updatedApp.NavigationItems[0]
		assert.Equal(t, constants.NavigationTypeObject, navItem.Type)
		assert.Equal(t, objName, navItem.ObjectAPIName)
		assert.Equal(t, "UIAPI Objects", navItem.Label)
	})

	t.Run("Create Object Without App (Nil AppID)", func(t *testing.T) {
		// This method requires appID string, so caller must handle nil check.
		// svc.CreateObjectWithApp takes `appID string`.
		// If caller passes empty string, what happens?
		// Logic:
		// schema.AppID = &appID
		// ...
		// app := s.metadataSvc.GetApp(ctx, appID)
		// if app == nil { return nil } -> Warns and returns nil (success for object creation)

		ctx := context.Background()
		uniqueID := time.Now().UnixNano()
		objName := fmt.Sprintf("uiapi_noapp_%d", uniqueID)

		schema := &models.ObjectMetadata{
			ID:          fmt.Sprintf("obj_noapp_%d", uniqueID),
			APIName:     objName,
			PluralLabel: "No App Objects",
			Label:       "No App Object",
		}
		defer func() { _ = ms.DeleteSchema(ctx, objName) }()

		// Pass non-existent app ID
		err := svc.CreateObjectWithApp(ctx, "non_existent_app_id", schema)
		require.NoError(t, err) // Should not fail, just skip nav item addition

		// Verify object created
		createdSchema := ms.GetSchema(ctx, objName)
		require.NotNil(t, createdSchema)
		assert.Equal(t, "non_existent_app_id", *createdSchema.AppID)
	})
}
