package analytics

import (
	"regexp"
	"strings"

	apperrors "github.com/nexuscrm/backend/pkg/errors"
	"github.com/nexuscrm/shared/pkg/api"
	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
)

// Aggregate Regex: Matches COUNT(Field), SUM(Field), etc.
var aggRegex = regexp.MustCompile(`(?i)(COUNT|SUM|AVG|MIN|MAX)\((.*)\)`)

func (qs *QueryService) buildAnalyticsQuery(req api.QueryRequest) (bool, *models.AnalyticsQuery, error) {
	// A query is an aggregate if it has a GROUP BY clause OR uses aggregate functions in SELECT
	hasGroupBy := req.GroupBy != ""

	var aggOp string
	var aggField string
	var aggType string

	// Scan SelectFields for Aggregates
	for _, field := range req.SelectFields {
		matches := aggRegex.FindStringSubmatch(field)
		if len(matches) == 3 {
			// matches[1] = OP (COUNT, SUM...), matches[2] = Field
			op := strings.ToUpper(matches[1])
			f := strings.TrimSpace(matches[2])

			// Constraint Check: Only one aggregate function supported for now
			if aggOp != "" {
				return false, nil, apperrors.NewValidationError("SelectFields", "multiple aggregate functions not yet supported")
			}

			aggType = op
			aggField = f

			// Map to normalized operation names required by RunAnalytics (count, sum, avg)
			switch op {
			case "COUNT":
				aggOp = constants.AnalyticsOperationCount
			case "SUM":
				aggOp = constants.AnalyticsOperationSum
			case "AVG":
				aggOp = constants.AnalyticsOperationAvg
			case "MIN":
				aggOp = "min" // Future support?
				return false, nil, apperrors.NewValidationError("SelectFields", "MIN aggregate not supported by repository yet")
			case "MAX":
				aggOp = "max" // Future support?
				return false, nil, apperrors.NewValidationError("SelectFields", "MAX aggregate not supported by repository yet")
			}
		}
	}

	// Case 1: If Group By exists, Operation MUST be 'group_by' for RunAnalytics to handle it correctly (it will look at AggregateType)
	if hasGroupBy {
		aggOp = constants.AnalyticsOperationGroupBy
	} else if aggOp == "" {
		// Case 2: No Group By, No Aggregate -> Not an analytics query
		return false, nil, nil
	}

	// Case 2: Aggregate without Group By (e.g. SELECT COUNT(Id) FROM Opp)
	if !hasGroupBy && aggOp == "" {
		return false, nil, nil // Not an aggregate query
	}

	// Construct AnalyticsQuery
	aq := &models.AnalyticsQuery{
		ObjectAPIName: req.ObjectAPIName,
		Operation:     aggOp,
		FilterExpr:    req.FilterExpr,
		GroupBy:       nil,
		Field:         nil,
		AggregateType: aggType,
		Having:        req.Having,
	}

	if req.GroupBy != "" {
		s := req.GroupBy
		aq.GroupBy = &s
	}

	if aggField != "" {
		aq.Field = &aggField
	}

	return true, aq, nil
}
