package onboarding

import (
	"context"
	"time"

	"github.com/tidbcloud/AgentTeam/internal/api"
	"github.com/tidbcloud/AgentTeam/internal/store/agent"
	"github.com/tidbcloud/AgentTeam/internal/store/attachment"
	"github.com/tidbcloud/AgentTeam/internal/store/identity"
	"github.com/tidbcloud/AgentTeam/internal/store/message"
	storeonboarding "github.com/tidbcloud/AgentTeam/internal/store/onboarding"
)

type Store interface {
	EnsureForUser(ctx context.Context, userID string, workspaceID string, locale string) (storeonboarding.EnsureResult, error)
	GetForUser(ctx context.Context, userID string, workspaceID string) (storeonboarding.State, error)
	AcknowledgeVisibleReply(ctx context.Context, userID string, workspaceID string, scopeID string, replyMessageID string) (storeonboarding.State, error)
}

type MockExchangeStateStore interface {
	ResolveMockAgentTarget(ctx context.Context, userID string, workspaceID string, tutorialChannelID string, agentID string) (storeonboarding.MockAgentTarget, error)
	ResolveMockReplyTarget(ctx context.Context, userID string, workspaceID string, threadScopeID string, agentID string, requestMessageID string, replyClientMessageID string) (storeonboarding.MockReplyTarget, error)
	RecordVisibleReply(ctx context.Context, evidence storeonboarding.VisibleReplyEvidence) error
}

type AgentStore interface {
	ListAgentsForWorkspaceWithOptions(ctx context.Context, userID string, workspaceID string, options agent.AppAgentListOptions) ([]agent.AppAgent, error)
}

type Runtime interface {
	api.AgentRuntimeOverlay
}

type MockMessageStore interface {
	SendDesktopOnboardingMockMessageForUser(ctx context.Context, user identity.User, workspaceID string, targetScopeID string, content string, mention *MockMention, clientMessageID string, startAgentThread bool) (message.AppMessage, message.MessageDelivery, error)
	SendDesktopOnboardingMockAgentReply(ctx context.Context, author MockAgentIdentity, targetRef string, content string, attachmentIDs []string, clientMessageID string) (message.MessageDelivery, error)
}

type MockMessageBackend interface {
	SendMessageForUserWithOptions(ctx context.Context, user identity.User, workspaceID string, targetScopeID string, content string, attachmentIDs []string, options message.HumanMessageCreateOptions) (message.AppMessage, message.MessageDelivery, error)
	SendAgentThreadMessage(ctx context.Context, authorAgent agent.AuthenticatedAgent, params message.SendMessageParams) (message.MessageDelivery, error)
}

type MockAttachmentStore interface {
	UploadDesktopOnboardingMockAttachment(ctx context.Context, memberID string, workspaceID string, scopeID string, input MockAttachment) (string, error)
}

type MockAttachmentBackend interface {
	UploadAttachmentsForMember(ctx context.Context, memberID string, workspaceID string, scopeID string, params []attachment.CreateAttachmentParams) ([]attachment.AppAttachment, error)
}

type MockMessageFanout interface {
	DeliverCommittedMessage(ctx context.Context, workspaceID string, appMessage message.AppMessage, delivery message.MessageDelivery) error
}

type MockAgentIdentity struct {
	AgentID     string
	WorkspaceID string
	MemberID    string
	MachineID   string
}

type MockAttachment struct {
	Filename    string
	ContentType string
	Blob        []byte
}

type MockMention struct {
	AgentID string
	Token   string
}

var ErrMockExchangeUnavailable = storeonboarding.ErrMockExchangeUnavailable

type VisibleReplyEvidence = storeonboarding.VisibleReplyEvidence

type clock func() time.Time
