package invocation

import (
	"context"
	"fmt"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/store/storeerr"
)

func (store *Store) ListInvocations(ctx context.Context, params ListParams) ([]ListItem, error) {
	if err := store.Validate(); err != nil {
		return nil, err
	}
	params.WorkspaceID = strings.TrimSpace(params.WorkspaceID)
	params.PlanID = strings.TrimSpace(params.PlanID)
	params.BeforeID = strings.TrimSpace(params.BeforeID)
	if params.WorkspaceID == "" || params.PlanID == "" {
		return nil, storeerr.BadRequest("workspaceId and planId are required")
	}
	if params.BeforeAcceptedAt.IsZero() != (params.BeforeID == "") {
		return nil, storeerr.BadRequest("beforeAcceptedAt and beforeId must be supplied together")
	}
	if params.Limit <= 0 {
		params.Limit = defaultListLimit
	}
	if params.Limit > maxListLimit {
		params.Limit = maxListLimit
	}
	var planExists int
	if err := store.db.QueryRow(ctx, `
SELECT COUNT(*)
FROM workflow_plans
WHERE workspace_id = $1 AND id = $2
`, params.WorkspaceID, params.PlanID).Scan(&planExists); err != nil {
		return nil, fmt.Errorf("check workflow Invocation Plan existence: %w", err)
	}
	if planExists == 0 {
		return nil, ErrNotFound
	}
	query := invocationListSelectSQL() + `
WHERE i.workspace_id = $1 AND i.plan_id = $2`
	args := []any{params.WorkspaceID, params.PlanID}
	if params.BeforeID != "" {
		query += `
  AND (i.accepted_at < $3 OR (i.accepted_at = $3 AND i.id < $4))`
		args = append(args, params.BeforeAcceptedAt.UTC(), params.BeforeID)
	}
	query += fmt.Sprintf("\nORDER BY i.accepted_at DESC, i.id DESC\nLIMIT $%d", len(args)+1)
	args = append(args, params.Limit)
	rows, err := store.db.Query(ctx, query, args...)
	if err != nil {
		return nil, fmt.Errorf("list workflow invocations: %w", err)
	}
	defer rows.Close()
	values := make([]ListItem, 0, params.Limit)
	for rows.Next() {
		value, err := scanInvocationListItem(rows)
		if err != nil {
			return nil, fmt.Errorf("scan workflow invocation list: %w", err)
		}
		values = append(values, value)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("iterate workflow invocation list: %w", err)
	}
	return values, nil
}
