// Package access owns domain-agnostic access-plane service helpers shared by resource domains. Access-change outbox events are refresh notifications rather than authoritative access state; sync lease requests are service contracts rather than token store models or API DTOs.
package access

import (
	"context"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/store/resource/memory"
)

const (
	AssetTypeMemory = memory.AssetTypeMemory
	AssetTypeSkill  = memory.AssetTypeSkill
	AssetTypeKB     = memory.AssetTypeKB
)

// DeduplicateAgentIDs trims blanks and preserves the first occurrence order.
func DeduplicateAgentIDs(agentIDs []string) []string {
	out := make([]string, 0, len(agentIDs))
	seen := make(map[string]struct{}, len(agentIDs))
	for _, id := range agentIDs {
		trimmed := strings.TrimSpace(id)
		if trimmed == "" {
			continue
		}
		if _, ok := seen[trimmed]; ok {
			continue
		}
		seen[trimmed] = struct{}{}
		out = append(out, trimmed)
	}
	return out
}

// OutboxStore is the narrow store surface needed to append one access-change
// notification inside the domain mutation transaction.
type OutboxStore interface {
	EnqueueAgentAssetAccessChange(context.Context, memory.AgentAssetAccessChangeInput) (memory.AgentAssetAccessChangeOutbox, error)
}

// EnqueueAccessChange appends an access-change notification and returns the
// monotonic outbox Version for stale-event guards.
func EnqueueAccessChange(ctx context.Context, store OutboxStore, input memory.AgentAssetAccessChangeInput) (int64, error) {
	if store == nil {
		return 0, nil
	}
	row, err := store.EnqueueAgentAssetAccessChange(ctx, input)
	if err != nil {
		return 0, err
	}
	return row.Version, nil
}
