// Filename: internal/pkg/reflectutil/structs.go
package reflectutil

import (
	"fmt"
	"reflect"
	"strconv"
)

// SetFieldFromString sets a struct field's value from a string.
func SetFieldFromString(field reflect.Value, value string) error {
	if !field.CanSet() {
		return fmt.Errorf("cannot set field")
	}
	switch field.Kind() {
	case reflect.Int, reflect.Int64:
		intVal, err := strconv.ParseInt(value, 10, 64)
		if err != nil {
			return err
		}
		field.SetInt(intVal)
	case reflect.String:
		field.SetString(value)
	case reflect.Bool:
		boolVal, err := strconv.ParseBool(value)
		if err != nil {
			return err
		}
		field.SetBool(boolVal)
	default:
		return fmt.Errorf("unsupported field type: %s", field.Type())
	}
	return nil
}

// FieldTypeToString converts a reflect.Type to a simple string representation.
func FieldTypeToString(t reflect.Type) string {
	switch t.Kind() {
	case reflect.Int, reflect.Int64:
		return "int"
	case reflect.String:
		return "string"
	case reflect.Bool:
		return "bool"
	default:
		return "unknown"
	}
}

// MergeNilFields uses reflection to merge non-nil pointer fields from 'override' into 'base'.
// Both base and override must be pointers to structs of the same type.
func MergeNilFields(base, override interface{}) error {
	baseVal := reflect.ValueOf(base)
	overrideVal := reflect.ValueOf(override)

	if baseVal.Kind() != reflect.Ptr || overrideVal.Kind() != reflect.Ptr {
		return fmt.Errorf("base and override must be pointers")
	}

	baseElem := baseVal.Elem()
	overrideElem := overrideVal.Elem()

	if baseElem.Kind() != reflect.Struct || overrideElem.Kind() != reflect.Struct {
		return fmt.Errorf("base and override must be pointers to structs")
	}

	if baseElem.Type() != overrideElem.Type() {
		return fmt.Errorf("base and override must be of the same struct type")
	}

	for i := 0; i < overrideElem.NumField(); i++ {
		overrideField := overrideElem.Field(i)
		if overrideField.Kind() == reflect.Ptr && !overrideField.IsNil() {
			baseField := baseElem.Field(i)
			if baseField.CanSet() {
				baseField.Set(overrideField)
			}
		}
	}
	return nil
}
