package localruntime

import (
	"time"

	"github.com/tidbcloud/AgentTeam/desktop/internal/profile"
	"github.com/tidbcloud/AgentTeam/desktop/internal/uisession"
)

// SubscriptionProvider is the contract seam the daemon events WS handler
// consumes. The GREEN implementation is *uisession.Store; handler tests
// inject a fake.
type SubscriptionProvider interface {
	Subscribe(sessionID string, expiresAt time.Time) (uisession.Subscription, error)
}

// LeaseTimerRegistry is the injectable lease-timer seam the WS handler
// uses to defer lease-expiry cleanup. The signature mirrors
// context.AfterFunc's stop-returning shape so the GREEN implementation
// can back it with time.AfterFunc without re-exporting.
type LeaseTimerRegistry interface {
	AfterFunc(d time.Duration, cb func()) (stop func())
}

type realLeaseTimerRegistry struct{}

func (realLeaseTimerRegistry) AfterFunc(d time.Duration, cb func()) func() {
	timer := time.AfterFunc(d, cb)
	return func() {
		timer.Stop()
	}
}

// resolveStreamServer returns the server for an active-selection stream
// frame. Disabled or missing servers return ok=false so the caller fails
// closed rather than emitting a half-resolved frame.
func resolveStreamServer(servers ServerRegistry, serverID string) (profile.AgentTeamServer, bool) {
	server, ok := servers.Get(serverID)
	if !ok || !server.Enabled {
		return profile.AgentTeamServer{}, false
	}
	return server, true
}

// mapSubscriptionState translates the Store-internal strong-typed enum to
// the wire `state` field (empty|selected|cleared). Unknown values return
// ok=false so the handler fails closed.
func mapSubscriptionState(state uisession.SubscriptionState) (string, bool) {
	switch state {
	case uisession.SubscriptionStateEmpty:
		return "empty", true
	case uisession.SubscriptionStateSelected:
		return "selected", true
	case uisession.SubscriptionStateCleared:
		return "cleared", true
	default:
		return "", false
	}
}

// mapChangeKind translates the Store-internal strong-typed enum to the
// wire event `type` for change frames. Unknown values return ok=false.
func mapChangeKind(kind uisession.ChangeKind) (string, bool) {
	switch kind {
	case uisession.ChangeKindSelected:
		return "selected", true
	case uisession.ChangeKindCleared:
		return "cleared", true
	case uisession.ChangeKindAdvanced:
		return "advanced", true
	default:
		return "", false
	}
}
