package issuetrackerconformance

import (
	"context"
	"errors"

	semantic "github.com/pingcap-inc/nexuscrm-contract/pkg/runtime/queryv1"
)

// QueryRecords is the public neutral semantic operation consumed by this
// CI-only non-CRM fixture. Runtime, transport, and storage remain injected by
// the test composition.
type QueryRecords func(context.Context, semantic.Request) (semantic.Response, error)

// IssueQueryConsumer is deliberately a consumer rather than an implementation
// of the L0 query engine. It owns only the Issue-shaped request used to prove
// that the neutral contract is usable without CRM query grammar.
type IssueQueryConsumer struct {
	query QueryRecords
}

func NewIssueQueryConsumer(query QueryRecords) (*IssueQueryConsumer, error) {
	if query == nil {
		return nil, errors.New("issue-tracker query conformance: query operation is required")
	}
	return &IssueQueryConsumer{query: query}, nil
}

// ListByRetryFloor sends one bounded request. The unsigned literal is
// intentional: the current public CRM SOQL path lowers numeric text to exact
// decimal, so this shape proves an independently usable neutral carrier.
func (c *IssueQueryConsumer) ListByRetryFloor(ctx context.Context, floor uint64) (semantic.Response, error) {
	request := IssueRetryFloorRequest(floor)
	if err := semantic.ValidateRequest(ctx, request); err != nil {
		return semantic.Response{}, err
	}
	response, err := c.query(ctx, request)
	if err != nil {
		return semantic.Response{}, err
	}
	if err := semantic.ValidateResponse(response); err != nil {
		return semantic.Response{}, err
	}
	return response, nil
}

func IssueRetryFloorRequest(floor uint64) semantic.Request {
	return semantic.Request{
		ObjectID: IssueObject,
		Selections: []semantic.Selection{
			{Kind: semantic.SelectionField, Field: "Id"},
			{Kind: semantic.SelectionField, Field: "RetryCount"},
			{Kind: semantic.SelectionField, Field: "Subject"},
		},
		Filter: semantic.Predicate{
			Kind:     semantic.PredicateFieldComparison,
			Field:    "RetryCount",
			Operator: semantic.ComparisonGreaterOrEqual,
			Value:    &semantic.Scalar{Unsigned: &floor},
		},
		OrderBy: []semantic.Sort{{Field: "Id", Direction: semantic.SortAscending}},
		Limit:   50,
	}
}
