package message

import (
	"context"
	"fmt"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/coredb"
)

func resolveServiceEventDeliverySources(ctx context.Context, queryer coredb.Queryer, workspaceID string, messageIDs []string) (map[string]ContributionSource, error) {
	cte, cteArgs, _, err := coredb.BuildStringValuesCTE("requested_messages", "message_id", messageIDs, 2)
	if err != nil {
		return nil, err
	}
	args := append([]any{workspaceID}, cteArgs...)
	rows, err := queryer.Query(ctx, fmt.Sprintf(`
WITH %s
SELECT
  requested_messages.message_id,
  delivery.id,
  delivery.event_id,
  delivery.event_type,
  delivery.event_action,
  delivery.subscription_kind,
  delivery.external_resource_key,
  COALESCE(service_definition.name, ''),
  COALESCE(service_definition.slug, '')
FROM requested_messages
JOIN service_event_deliveries delivery
  ON delivery.workspace_id = $1
 AND delivery.message_id = requested_messages.message_id
LEFT JOIN service_definitions service_definition
  ON service_definition.id = delivery.service_definition_id
ORDER BY delivery.completed_at DESC, delivery.attempted_at DESC, delivery.id DESC
`, cte), args...)
	if err != nil {
		return nil, fmt.Errorf("load service event delivery contribution sources: %w", err)
	}
	defer rows.Close()
	byMessageID := make(map[string]ContributionSource)
	for rows.Next() {
		var messageID string
		var deliveryID string
		var eventID string
		var eventType string
		var eventAction string
		var subscriptionKind string
		var externalResourceKey string
		var serviceName string
		var serviceSlug string
		if err := rows.Scan(
			&messageID,
			&deliveryID,
			&eventID,
			&eventType,
			&eventAction,
			&subscriptionKind,
			&externalResourceKey,
			&serviceName,
			&serviceSlug,
		); err != nil {
			return nil, fmt.Errorf("scan service event delivery contribution source: %w", err)
		}
		messageID = strings.TrimSpace(messageID)
		if messageID == "" {
			continue
		}
		if _, exists := byMessageID[messageID]; exists {
			continue
		}
		byMessageID[messageID] = ContributionSourceForServiceEventDelivery(ServiceEventDeliveryContributionSourceParams{
			DeliveryID:  deliveryID,
			Label:       serviceEventDeliverySourceLabel(serviceName, serviceSlug, subscriptionKind, externalResourceKey),
			EventID:     eventID,
			EventType:   eventType,
			EventAction: eventAction,
		})
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("iterate service event delivery contribution sources: %w", err)
	}
	return byMessageID, nil
}

func serviceEventDeliverySourceLabel(serviceName string, serviceSlug string, subscriptionKind string, externalResourceKey string) string {
	serviceLabel := firstNonEmptyString(serviceName, serviceSlug)
	resourceKey := strings.TrimSpace(externalResourceKey)
	if serviceLabel == "" {
		return resourceKey
	}
	if resourceKey == "" {
		return serviceLabel
	}
	switch strings.TrimSpace(subscriptionKind) {
	case "pull_request":
		return serviceLabel + " watch " + resourceKey
	default:
		return serviceLabel + " event " + resourceKey
	}
}
