package app

import (
	"context"
	"fmt"
	"strings"
	"time"

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

func markServiceEventSubscriptionDelivered(ctx context.Context, execer coredb.QueryExecer, subscriptionIDs []string, now time.Time) error {
	ids := normalizeNonEmptyStrings(subscriptionIDs)
	if len(ids) == 0 {
		return nil
	}
	subscriptionIDsCTE, subscriptionIDArgs, _, err := coredb.BuildStringValuesCTE("delivered_subscription_ids", "subscription_id", ids, 2)
	if err != nil {
		return fmt.Errorf("build delivered service event subscription ids: %w", err)
	}
	query := fmt.Sprintf(`
WITH %s
UPDATE service_event_subscriptions
SET last_delivery_at = $1,
    last_success_at = $1,
    last_failure_at = NULL,
    last_failure_code = '',
    last_failure_detail = '',
    updated_at = $1
WHERE EXISTS (
      SELECT 1
      FROM delivered_subscription_ids
      WHERE delivered_subscription_ids.subscription_id = id
)
`, subscriptionIDsCTE)
	args := append([]any{now}, subscriptionIDArgs...)
	if _, err = execer.Exec(ctx, query, args...); err != nil {
		return fmt.Errorf("mark service event subscriptions delivered: %w", err)
	}
	return nil
}

func completeServiceEventSubscriptionAfterTerminalEvent(ctx context.Context, execer coredb.QueryExecer, workspaceID string, subscriptionID string, now time.Time) error {
	trimmedWorkspaceID := strings.TrimSpace(workspaceID)
	trimmedSubscriptionID := strings.TrimSpace(subscriptionID)
	if trimmedWorkspaceID == "" || trimmedSubscriptionID == "" {
		return nil
	}
	_, err := execer.Exec(ctx, `
UPDATE service_event_subscriptions
SET status = $3,
    active_subscription_key = NULL,
    paused_reason = '',
    paused_at = NULL,
    removed_at = $4,
    updated_at = $4
WHERE workspace_id = $1
  AND id = $2
  AND removed_at IS NULL
`, trimmedWorkspaceID, trimmedSubscriptionID, ServiceEventSubscriptionStatusCompleted, now)
	if err != nil {
		return fmt.Errorf("complete service event subscription after terminal event: %w", err)
	}
	return nil
}

func markServiceEventSubscriptionDeliveryFailure(ctx context.Context, execer coredb.QueryExecer, subscriptionID string, code string, message string, now time.Time) error {
	trimmedSubscriptionID := strings.TrimSpace(subscriptionID)
	if trimmedSubscriptionID == "" {
		return nil
	}
	trimmedMessage := strings.TrimSpace(message)
	if len(trimmedMessage) > 1024 {
		trimmedMessage = trimmedMessage[:1024]
	}
	_, err := execer.Exec(ctx, `
UPDATE service_event_subscriptions
SET last_failure_at = $1,
    last_failure_code = $2,
    last_failure_detail = $3,
    updated_at = $1
WHERE id = $4
`, now, strings.TrimSpace(code), trimmedMessage, trimmedSubscriptionID)
	if err != nil {
		return fmt.Errorf("mark service event subscription failure: %w", err)
	}
	return nil
}
