package analytics

import (
	"context"
	"testing"

	"github.com/nexuscrm/kernel/pkg/ports"
	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
	"github.com/nexuscrm/shared/pkg/queryspec"
)

type reportPaginationQueryStub struct {
	ports.QueryService
	querySpec      queryspec.QuerySpec
	analyticsQuery models.AnalyticsQuery
}

func (s *reportPaginationQueryStub) QueryWithSpec(
	_ context.Context,
	request queryspec.QuerySpec,
	_ *models.UserSession,
) (*models.QueryResult, error) {
	s.querySpec = request
	return &models.QueryResult{Records: []models.SObject{{"Id": "work-11"}}, TotalSize: 30}, nil
}

func (s *reportPaginationQueryStub) RunAnalytics(
	_ context.Context,
	request models.AnalyticsQuery,
	_ *models.UserSession,
) (interface{}, error) {
	s.analyticsQuery = request
	return []models.SObject{{"name": "open", "val": int64(11)}}, nil
}

type reportPaginationMetadata struct{ MetadataSource }

func (reportPaginationMetadata) GetSchema(_ context.Context, objectAPIName string) *models.ObjectMetadata {
	if objectAPIName != "WorkItem" {
		return nil
	}
	return &models.ObjectMetadata{
		APIName: "WorkItem",
		Fields: []models.FieldMetadata{
			{APIName: "Id", Type: constants.FieldTypeString},
			{APIName: "Status", Type: constants.FieldTypeString},
		},
	}
}

func TestPhysicalReportExecutionConsumesPageBounds(t *testing.T) {
	t.Run("tabular query", func(t *testing.T) {
		query := &reportPaginationQueryStub{}
		service := NewReportService(query, reportPaginationMetadata{}, nil, nil)
		_, err := service.RunReportDefinitionPage(
			context.Background(),
			&models.ReportDefinition{
				ID: "open-work", SourceObject: "WorkItem",
				DisplayMode: "TABULAR", Columns: []string{"Id"},
			},
			&models.UserSession{ID: "user-1"}, map[string]interface{}{}, 25, 10,
		)
		if err != nil {
			t.Fatal(err)
		}
		if query.querySpec.Limit != 25 || query.querySpec.Offset != 10 {
			t.Fatalf("query page = limit %d offset %d, want 25/10", query.querySpec.Limit, query.querySpec.Offset)
		}
	})

	t.Run("grouped query", func(t *testing.T) {
		query := &reportPaginationQueryStub{}
		service := NewReportService(query, reportPaginationMetadata{}, nil, nil)
		_, err := service.RunReportDefinitionPage(
			context.Background(),
			&models.ReportDefinition{
				ID: "work-by-status", SourceObject: "WorkItem",
				DisplayMode: "SUMMARY", Grouping: []string{"Status"},
				Aggregates: []models.ReportAggregate{{Field: "Id", Type: "COUNT"}},
			},
			&models.UserSession{ID: "user-1"}, map[string]interface{}{}, 25, 10,
		)
		if err != nil {
			t.Fatal(err)
		}
		if query.analyticsQuery.Limit != 25 || query.analyticsQuery.Offset != 10 {
			t.Fatalf("analytics page = limit %d offset %d, want 25/10", query.analyticsQuery.Limit, query.analyticsQuery.Offset)
		}
	})
}
