package mcp

import (
	"context"
	"crypto/sha256"
	"fmt"
	"strings"

	"github.com/google/uuid"
	"github.com/tidbcloud/AgentTeam/desktop/internal/types"
	"github.com/tidbcloud/AgentTeam/desktop/internal/wire/apiclient"
)

func (h *mcpHandler) AcknowledgeMCPToolResultDelivery(agentID string, runtimeSessionID string, receipts []string, outcome types.MCPToolDeliveryOutcome) {
	if h == nil || h.c == nil || h.runtime == nil || len(receipts) == 0 {
		return
	}
	h.runtime.AcknowledgeRuntimeMessageToolDeliveriesForSession(agentID, receipts, outcome, runtimeSessionID)
}

func filterFreshnessTargetMessages(messages []types.InboxMessage, targetKey string) []types.InboxMessage {
	targetKey = strings.TrimSpace(targetKey)
	if targetKey == "" || len(messages) == 0 {
		return nil
	}
	filtered := messages[:0]
	for _, msg := range messages {
		if strings.TrimSpace(msg.TargetKey) == targetKey {
			filtered = append(filtered, msg)
		}
	}
	return filtered
}

func firstToolText(result *types.MCPToolResult) string {
	if result == nil || len(result.Content) == 0 {
		return ""
	}
	return result.Content[0].Text
}

func (h *mcpHandler) resolveFreshnessTargetKey(ctx context.Context, api *apiclient.Client, target string) (string, error) {
	resolved, err := api.ResolveTarget(ctx, target, apiclient.ResolvePurposeWritable)
	if err != nil {
		return "", fmt.Errorf("resolve freshness target: %w", err)
	}
	return resolved.TargetKey, nil
}

func newAgentToolSentMessageID() string {
	return "agent-send-" + strings.ToLower(uuid.NewString())
}

func partialSendSignature(target string, chunks []string, attachmentIDs []string, teamInvokeTeamID string) string {
	if len(chunks) <= 1 || len(attachmentIDs) > 0 {
		return ""
	}
	var b strings.Builder
	b.WriteString(strings.TrimSpace(target))
	b.WriteByte(0)
	b.WriteString(strings.TrimSpace(teamInvokeTeamID))
	b.WriteByte(0)
	for _, chunk := range chunks {
		b.WriteString(chunk)
		b.WriteByte(0)
	}
	sum := sha256.Sum256([]byte(b.String()))
	return fmt.Sprintf("%x", sum[:])
}

func normalizeAgentSendState(state string, messageID string) string {
	switch strings.TrimSpace(state) {
	case agentSendStateSent, agentSendStateAlreadySent, agentSendStateHeld:
		return strings.TrimSpace(state)
	case "":
		if strings.TrimSpace(messageID) != "" {
			return agentSendStateSent
		}
	}
	return strings.TrimSpace(state)
}

func (h *mcpHandler) rememberSendAccepted(agentID string, target string, result agentSendMessageResponse) {
	tracker := h.freshnessTracker()
	if tracker == nil || strings.TrimSpace(result.TargetKey) == "" || result.AcceptedSeq <= 0 {
		return
	}
	tracker.RememberMessageFreshnessObserved(agentID, []types.InboxMessage{{
		MessageID: strings.TrimSpace(result.MessageID),
		Target:    strings.TrimSpace(target),
		TargetKey: strings.TrimSpace(result.TargetKey),
		TargetSeq: result.AcceptedSeq,
	}})
}

func (h *mcpHandler) rememberSendHeld(agentID string, result agentSendMessageResponse) {
	tracker := h.freshnessTracker()
	if tracker == nil || strings.TrimSpace(result.TargetKey) == "" {
		return
	}
	latestSeq := result.LatestSeq
	if latestSeq == 0 {
		latestSeq = result.NeedsRefreshUntilSeq
	}
	tracker.RememberMessageFreshnessHeld(agentID, result.TargetKey, result.SeenUpToSeq, latestSeq)
}
