package agent

import (
	"context"

	"github.com/tidbcloud/AgentTeam/internal/store/agent"
	"github.com/tidbcloud/AgentTeam/internal/store/message"
)

// ReactionStore is the narrow storage surface needed by reaction endpoints.
type ReactionStore interface {
	ResolveReactionMessageIDForAgent(ctx context.Context, agent agent.AuthenticatedAgent, messageID string) (string, error)
	GetMessageReactionsForAgent(ctx context.Context, agent agent.AuthenticatedAgent, messageID string) ([]message.MessageReactionAggregate, error)
	AddReactionForAgent(ctx context.Context, agent agent.AuthenticatedAgent, messageID string, emoji string) (message.AddReactionResult, error)
	RemoveReactionForAgent(ctx context.Context, agent agent.AuthenticatedAgent, messageID string, emoji string) (message.RemoveReactionResult, error)
}

// ReactionFanout emits committed reaction side effects through the canonical
// browser and daemon fanout path.
type ReactionFanout interface {
	DeliverReactionAdded(ctx context.Context, workspaceID string, messageID string, result message.AddReactionResult, reactions []message.MessageReactionAggregate)
	DeliverReactionRemoved(ctx context.Context, workspaceID string, messageID string, result message.RemoveReactionResult, reactions []message.MessageReactionAggregate)
}

func (h *ReactionHandler) getReactions(ctx context.Context, authenticatedAgent agent.AuthenticatedAgent, messageID string) ([]message.MessageReactionAggregate, error) {
	resolvedMessageID, err := h.store.ResolveReactionMessageIDForAgent(ctx, authenticatedAgent, messageID)
	if err != nil {
		return nil, err
	}
	return h.store.GetMessageReactionsForAgent(ctx, authenticatedAgent, resolvedMessageID)
}

func (h *ReactionHandler) addReaction(ctx context.Context, authenticatedAgent agent.AuthenticatedAgent, messageID string, emoji string) (bool, []message.MessageReactionAggregate, error) {
	resolvedMessageID, err := h.store.ResolveReactionMessageIDForAgent(ctx, authenticatedAgent, messageID)
	if err != nil {
		return false, nil, err
	}
	result, err := h.store.AddReactionForAgent(ctx, authenticatedAgent, resolvedMessageID, emoji)
	if err != nil {
		return false, nil, err
	}
	reactions, err := h.store.GetMessageReactionsForAgent(ctx, authenticatedAgent, resolvedMessageID)
	if err != nil {
		return false, nil, err
	}
	if result.Changed && h.fanout != nil {
		h.fanout.DeliverReactionAdded(ctx, authenticatedAgent.WorkspaceID, resolvedMessageID, result, reactions)
	}
	return result.Changed, reactions, nil
}

func (h *ReactionHandler) removeReaction(ctx context.Context, authenticatedAgent agent.AuthenticatedAgent, messageID string, emoji string) (bool, []message.MessageReactionAggregate, error) {
	resolvedMessageID, err := h.store.ResolveReactionMessageIDForAgent(ctx, authenticatedAgent, messageID)
	if err != nil {
		return false, nil, err
	}
	result, err := h.store.RemoveReactionForAgent(ctx, authenticatedAgent, resolvedMessageID, emoji)
	if err != nil {
		return false, nil, err
	}
	reactions, err := h.store.GetMessageReactionsForAgent(ctx, authenticatedAgent, resolvedMessageID)
	if err != nil {
		return false, nil, err
	}
	if result.Changed && h.fanout != nil {
		h.fanout.DeliverReactionRemoved(ctx, authenticatedAgent.WorkspaceID, resolvedMessageID, result, reactions)
	}
	return result.Changed, reactions, nil
}
