package kb

import (
	"context"
	"reflect"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
)

func TestKnowledgeBaseSetupSessionUsesExactVersionFence(t *testing.T) {
	store := newTestStore(t)
	ctx := context.Background()
	now := time.Date(2026, 8, 9, 1, 2, 3, 0, time.UTC)
	created, err := store.CreateKnowledgeBaseSetupSession(ctx, KnowledgeBaseSetupSession{
		ID: "kbs_1", WorkspaceID: "ws_1", KnowledgeBaseID: "kb_1", Mode: "create_draft",
		ActiveStep: "basic", WorkingRevision: "kbr_1", Version: 1,
		CreatedBy: "user_1", UpdatedBy: "user_1", CreatedAt: now, UpdatedAt: now,
	})
	require.NoError(t, err)
	require.EqualValues(t, 1, created.Version)

	updated, ok, err := store.UpdateKnowledgeBaseSetupStep(ctx, "ws_1", "kb_1", "sources", "user_1", 1, now.Add(time.Minute))
	require.NoError(t, err)
	require.True(t, ok)
	require.Equal(t, "sources", updated.ActiveStep)
	require.EqualValues(t, 2, updated.Version)

	_, ok, err = store.UpdateKnowledgeBaseSetupStep(ctx, "ws_1", "kb_1", "review", "user_1", 1, now.Add(2*time.Minute))
	require.NoError(t, err)
	require.False(t, ok)

	otherWorkspace, err := store.CreateKnowledgeBaseSetupSession(ctx, KnowledgeBaseSetupSession{
		ID: "kbs_foreign", WorkspaceID: "ws_foreign", KnowledgeBaseID: "kb_foreign", Mode: "create_draft",
		ActiveStep: "review", WorkingRevision: "kbr_foreign", Version: 1,
		CreatedBy: "user_2", UpdatedBy: "user_2", CreatedAt: now, UpdatedAt: now,
	})
	require.NoError(t, err)
	sessions, err := store.ListKnowledgeBaseSetupSessions(ctx, "ws_1", []string{"kb_1", otherWorkspace.KnowledgeBaseID})
	require.NoError(t, err)
	require.Len(t, sessions, 1)
	require.Equal(t, "kb_1", sessions[0].KnowledgeBaseID)
	require.Equal(t, "sources", sessions[0].ActiveStep)
}

func TestKnowledgeBaseSetupArtifactUpsertKeepsOneScopedDisposition(t *testing.T) {
	store := newTestStore(t)
	ctx := context.Background()
	now := time.Date(2026, 8, 9, 1, 2, 3, 0, time.UTC)
	first, err := store.UpsertKnowledgeBaseSetupSourceArtifact(ctx, KnowledgeBaseSetupSourceArtifact{
		ID: "kbsa_1", WorkspaceID: "ws_1", KnowledgeBaseID: "kb_1", SourceID: "src_1",
		Kind: "wiki", State: "skipped", UpdatedBy: "user_1", CreatedAt: now, UpdatedAt: now,
	})
	require.NoError(t, err)
	second, err := store.UpsertKnowledgeBaseSetupSourceArtifact(ctx, KnowledgeBaseSetupSourceArtifact{
		ID: "kbsa_replay", WorkspaceID: "ws_1", KnowledgeBaseID: "kb_1", SourceID: "src_1",
		Kind: "wiki", State: "not_requested", UpdatedBy: "user_2", CreatedAt: now, UpdatedAt: now.Add(time.Minute),
	})
	require.NoError(t, err)
	require.Equal(t, first.ID, second.ID)
	require.Equal(t, "not_requested", second.State)
	require.Equal(t, "user_2", second.UpdatedBy)
}

func TestKnowledgeBaseSetupModelsHaveNoJSONTags(t *testing.T) {
	for _, model := range []any{KnowledgeBaseSetupSession{}, KnowledgeBaseSetupSummary{}, KnowledgeBaseSetupSourceArtifact{}, KnowledgeBaseGenerationRequest{}, KnowledgeBasePublicationRequest{}} {
		typeOfModel := reflect.TypeOf(model)
		for index := 0; index < typeOfModel.NumField(); index++ {
			field := typeOfModel.Field(index)
			_, present := field.Tag.Lookup("json")
			require.False(t, present, "%s.%s must not define a JSON tag", typeOfModel.Name(), field.Name)
		}
	}
}
