package im

import (
	"fmt"
	"strings"
	"time"

	"github.com/tidbcloud/AgentTeam/internal/core/identifiers"
	"github.com/tidbcloud/AgentTeam/internal/coredb"
	"github.com/tidbcloud/AgentTeam/internal/store/model"
)

const (
	defaultStreamEventListLimit      = 500
	maxStreamEventListLimit          = 1000
	defaultConversationIndexListSize = 50
	maxConversationIndexListSize     = 200
	MaxConversationLookupIDs         = 50
)

// Store provides TiDB-backed Workspace IM stream primitives.
type Store struct {
	db coredb.DB
}

// New creates a Store using the shared coredb seam.
func New(db coredb.DB) *Store {
	return &Store{db: db}
}

// Validate checks mandatory dependencies at process composition time.
func (store *Store) Validate() error {
	return nil
}

func normalizeLimit(limit int, defaultLimit int, maxLimit int) int {
	if limit <= 0 {
		return defaultLimit
	}
	if limit > maxLimit {
		return maxLimit
	}
	return limit
}

func normalizedString(value string) string {
	trimmed := strings.TrimSpace(value)
	if trimmed == "" {
		return ""
	}
	return trimmed
}

func requireWorkspaceMember(workspaceID string, memberID string) (string, string, error) {
	workspaceID = normalizedString(workspaceID)
	memberID = normalizedString(memberID)
	if workspaceID == "" {
		return "", "", fmt.Errorf("workspace id is required")
	}
	if memberID == "" {
		return "", "", fmt.Errorf("member id is required")
	}
	return workspaceID, memberID, nil
}

func encodeJSONMap(value map[string]any, defaultEmpty bool) ([]byte, error) {
	encoded, err := model.MarshalJSONMap(value, defaultEmpty)
	if err != nil {
		return nil, fmt.Errorf("encode json map: %w", err)
	}
	return encoded, nil
}

func decodeJSONMap(raw []byte) (map[string]any, error) {
	decoded, err := model.UnmarshalJSONMap(raw)
	if err != nil {
		return nil, fmt.Errorf("decode json map: %w", err)
	}
	return decoded, nil
}

func nowUTC() time.Time { return time.Now().UTC() }

func ensureEventID(eventID string) (string, error) {
	if trimmed := normalizedString(eventID); trimmed != "" {
		return trimmed, nil
	}
	id, err := identifiers.NewEntityID("imevt")
	if err != nil {
		return "", fmt.Errorf("generate im event id: %w", err)
	}
	return id, nil
}
