package prediction

import (
	"encoding/json"
	"fmt"

	"github.com/rose_cat707/luminary/internal/model"
)

func ParseInputDefaults(raw string) (map[string]any, error) {
	if raw == "" || raw == "{}" {
		return map[string]any{}, nil
	}
	var out map[string]any
	if err := json.Unmarshal([]byte(raw), &out); err != nil {
		return nil, err
	}
	if out == nil {
		return map[string]any{}, nil
	}
	return out, nil
}

func effectiveDefault(d ParamDef, overrides map[string]any) (any, bool) {
	if overrides != nil {
		if v, ok := overrides[d.Name]; ok {
			return v, true
		}
	}
	if d.Default != nil {
		return d.Default, true
	}
	return nil, false
}

func ValidateInputWithDefaults(wt model.WorkflowType, input map[string]any, overrides map[string]any) (map[string]any, error) {
	defs := ParamsForWorkflowType(wt)
	out := make(map[string]any, len(defs))
	for _, d := range defs {
		v, ok := input[d.Name]
		if !ok || v == nil {
			if def, has := effectiveDefault(d, overrides); has {
				coerced, err := coerceValue(d, def)
				if err != nil {
					return nil, fmt.Errorf("%s: %w", d.Name, err)
				}
				out[d.Name] = coerced
				continue
			}
			if d.Required {
				return nil, fmt.Errorf("missing required field: %s", d.Name)
			}
			continue
		}
		coerced, err := coerceValue(d, v)
		if err != nil {
			return nil, fmt.Errorf("%s: %w", d.Name, err)
		}
		out[d.Name] = coerced
	}
	return out, nil
}
