package knowledgeqa

import (
	"context"
	"time"

	"github.com/tidbcloud/AgentTeam/internal/api"
	"github.com/tidbcloud/AgentTeam/internal/forwarder"
	"github.com/tidbcloud/AgentTeam/internal/knowledgeqa/protocol"
	"github.com/tidbcloud/AgentTeam/internal/maas/availability"
)

type ConversationService interface {
	CreateSession(context.Context, CreateSessionParams) (Session, error)
	LoadSessionForOwner(context.Context, string, string, string) (Session, error)
	ListTurnsForOwner(context.Context, string, string, string, int) ([]Turn, error)
	LoadFeedbackSnapshotForOwner(context.Context, string, string, string, string) (FeedbackSnapshot, error)
	LoadCitationForOwner(context.Context, string, string, string, string) (Citation, error)
	CreateTurn(context.Context, CreateTurnParams) (Turn, error)
	RetryTurn(context.Context, RetryTurnParams) (Turn, error)
	StopTurnForOwner(context.Context, string, string, string, time.Time) (Turn, error)
	DeleteSessionConversationForOwner(context.Context, string, string, string, time.Time) (Session, error)
}

type FeedbackService interface {
	UpsertFeedback(context.Context, UpsertFeedbackParams) (Feedback, error)
	ListFeedbackForThread(context.Context, string, string, string) ([]Feedback, error)
	DeleteFeedback(context.Context, string, string, string) error
}

type SharingService interface {
	CreateShare(context.Context, string, string, string, string, time.Time) (Share, error)
	OpenShare(context.Context, string, string, time.Time) (Share, error)
	LoadReceivedShare(context.Context, string, string, time.Time) (Share, error)
	LoadReceivedShareCitation(context.Context, string, string, string) (ShareCitation, error)
	ListReceivedShares(context.Context, string, int) ([]Share, error)
}

type CitationOpener interface {
	OpenKnowledgeQACitation(context.Context, forwarder.KnowledgeQACitationOpenRequest) (forwarder.KnowledgeQACitationOpenResult, error)
}

type PolicyResolver interface {
	LoadOrganizationPolicy(context.Context, string) (protocol.OrganizationPolicy, error)
	ResolveEffectivePolicy(context.Context, string, string, string, string) (protocol.EffectivePolicy, error)
}

type OrganizationResolver interface {
	GetWorkspaceOrganizationForUser(context.Context, string, string) (Organization, error)
}

type HostedAvailabilityResolver interface {
	LoadHostedAvailability(context.Context, string) (availability.Availability, error)
}

// QueueNotifier is only a low-latency wake-up signal. The database queue is
// authoritative, so losing a notification or a browser connection cannot lose
// a turn. A worker must claim and execute queued attempts independently.
type QueueNotifier interface {
	NotifyKnowledgeQATurnQueued(context.Context, string, string, string)
	CancelKnowledgeQATurn(context.Context, string, string)
}

type TurnUpdateNotifier interface {
	NotifyKnowledgeQATurnUpdated(context.Context, protocol.TurnUpdate)
}

type Dependencies struct {
	SessionAuth               api.SessionAuthenticator
	WorkspaceStore            api.WorkspaceResolver
	Sessions                  ConversationService
	Policies                  PolicyResolver
	Organizations             OrganizationResolver
	HostedAvailability        HostedAvailabilityResolver
	Queue                     QueueNotifier
	TurnUpdates               TurnUpdateNotifier
	Citations                 CitationOpener
	Feedbacks                 FeedbackService
	Sharing                   SharingService
	PublicBaseURL             string
	EmailVerificationRequired bool
}
