package query_params

import (
	"strings"

	"git.ma-al.com/goc_daniel/b2b/app/utils/query/filters"
	"github.com/gofiber/fiber/v3"
)

// ParseWhereScopes will attempt to create where scope query filters from url
// query params. It will map form fields to a database column name using
// `MapParamsKeyToDbColumn` function.
func ParseWhereScopes[T any](c fiber.Ctx, ignoredKeys []string, formColumnMapping ...map[string]string) []filters.Filter {
	var parsedFilters []filters.Filter
	//nolint
	for key, value := range c.Request().URI().QueryArgs().All() {
		keyStr := string(key)
		valStr := string(value)
		isIgnored := false
		for _, ignoredKey := range ignoredKeys {
			if keyStr == ignoredKey {
				isIgnored = true
				break
			}
		}
		if isIgnored {
			continue
		}

		baseKey, operator := extractOperator(keyStr)

		if col, err := MapParamsKeyToDbColumn[T](baseKey, formColumnMapping...); err == nil {
			if strings.HasPrefix(valStr, "~") {
				parsedFilters = append(parsedFilters, filters.WhereFromStrings(col, "LIKE", valStr))
				continue
			}

			op := resolveOperator(operator)

			parsedFilters = append(parsedFilters, filters.WhereFromStrings(col, op, valStr))
		}
	}

	return parsedFilters
}

func extractOperator(key string) (base string, operatorSuffix string) {
	suffixes := []string{"_gt", "_gte", "_lt", "_lte", "_eq", "_neq", "_in"}
	for _, suf := range suffixes {
		if strings.HasSuffix(key, suf) {
			return strings.TrimSuffix(key, suf), suf[1:]
		}
	}
	return key, ""
}

func resolveOperator(suffix string) string {
	switch suffix {
	case "gt":
		return ">"
	case "gte":
		return ">="
	case "lt":
		return "<"
	case "lte":
		return "<="
	case "neq":
		return "!="
	case "eq":
		return "="
	case "in":
		return "IN"
	default:
		return "LIKE"
	}
}
