package query_params

import (
	"fmt"
	"reflect"
	"strings"

	mreflect "git.ma-al.com/goc_daniel/b2b/app/utils/reflect"
)

// MapParamsKeyToDbColumn will attempt to map provided key into unique (prefixed
// with table) column name. It will do so using following priority of sources of
// mapping:
// 1. `formColumnMapping` argument. If the mapped values contain a dot, the part
// before the dot will be used for the table name. Otherwise the table name will
// be derived from the generic parameter `T`.
// 2. json tags of provided as generic `T` struct. The table name will be also
// derived from the generic if not provided as dot prefix.
func MapParamsKeyToDbColumn[DEFAULT_TABLE_MODEL any](key string, mapping ...map[string]string) (string, error) {
	ERR := "Failed to find appropiate mapping from form field to database column for key: '%s', and default table name: '%s'"

	if len(mapping) > 0 {
		if field, ok := (mapping[0])[key]; ok {
			return field, nil
		}
	} else {
		var t DEFAULT_TABLE_MODEL
		if table, field, ok := strings.Cut(key, "."); ok {
			if column, err := mreflect.GetGormColumnFromJsonField(field, reflect.TypeOf(t)); err == nil {
				return table + "." + column, nil
			}
			return "", fmt.Errorf(ERR, key, table)
		} else {
			table := mreflect.GetTableName[DEFAULT_TABLE_MODEL]()
			if column, err := mreflect.GetGormColumnFromJsonField(key, reflect.TypeOf(t)); err == nil {
				return table + "." + column, nil
			} else {
				return "", fmt.Errorf(ERR, key, table)
			}
		}
	}
	return "", fmt.Errorf(ERR, key, mreflect.GetTableName[DEFAULT_TABLE_MODEL]())
}
