package query

import (
	"fmt"
	"strings"
)

// formulaQueryOperators lists the supported comparison operators in order of
// specificity (multi-char first) shared by ParseFormulaQuery and
// FormulaQueryField so the two stay in lockstep.
var formulaQueryOperators = []struct {
	symbol string
	sqlOp  string
}{
	{"!=", "!="}, {"<>", "!="}, {">=", ">="}, {"<=", "<="},
	{"=", "="}, {">", ">"}, {"<", "<"},
}

// FormulaQueryField reports the field name a term would parse to as a formula
// query (`field op value`), or ("", false) if the term is not a formula-query
// shape. It applies the exact same operator scan and field-name validation as
// ParseFormulaQuery, so callers can decide base-table eligibility from the
// field name WITHOUT first knowing the read table (which ParseFormulaQuery
// needs to build the qualified SQL). The returned field is the raw typed API
// name — ParseFormulaQuery emits it unmapped as `table`.`field`, so a view-only
// or PhysicalName-aliased field cannot be read from the base table.
func FormulaQueryField(term string) (string, bool) {
	for _, op := range formulaQueryOperators {
		if idx := strings.Index(term, op.symbol); idx > 0 {
			field := strings.TrimSpace(term[:idx])
			value := strings.TrimSpace(term[idx+len(op.symbol):])
			if field == "" || value == "" {
				continue
			}
			for _, c := range field {
				if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_') {
					return "", false
				}
			}
			return field, true
		}
	}
	return "", false
}

// ParseFormulaQuery parses simple formula expressions like "field = value" or "field > 100"
// Returns SQL condition, params, and true if successfully parsed as formula
func ParseFormulaQuery(term, objectName string) (string, []interface{}, bool) {
	for _, op := range formulaQueryOperators {
		if idx := strings.Index(term, op.symbol); idx > 0 {
			field := strings.TrimSpace(term[:idx])
			value := strings.TrimSpace(term[idx+len(op.symbol):])

			// Validate field name (basic sanity check - alphanumeric + underscore)
			if field == "" || value == "" {
				continue
			}
			for _, c := range field {
				if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_') {
					return "", nil, false // Invalid field name
				}
			}

			// Build SQL condition
			condition := fmt.Sprintf("`%s`.`%s` %s ?", objectName, field, op.sqlOp)
			return condition, []interface{}{value}, true
		}
	}

	return "", nil, false
}
