package records

import (
	"fmt"
	"strings"

	"github.com/nexuscrm/kernel/pkg/passwordhash"
	"github.com/nexuscrm/kernel/pkg/utils"
	"github.com/nexuscrm/shared/pkg/constants"
)

// applyUserDefaults sets Username from Email if missing and hashes/stamps
// passwords for User inserts. Caller-authored profile/name fields remain
// owned by the input + schema contract rather than being rewritten here.
func applyUserDefaults(data map[string]interface{}) error {
	applyUserUsernameDefault(data)
	return applyUserPasswordDefaults(data)
}

func applyUserUsernameDefault(data map[string]interface{}) {
	// Username = Email when Username is missing/empty.
	uname, hasUname := data[constants.FieldUsername].(string)
	if !hasUname || uname == "" {
		if email, ok := data[constants.FieldEmail].(string); ok && email != "" {
			data[constants.FieldUsername] = email
		}
	}
}

func applyUserPasswordDefaults(data map[string]interface{}) error {
	pwd, hasPwd := data[constants.FieldPassword].(string)
	if hasPwd && pwd != "" {
		if strings.HasPrefix(pwd, "$2") {
			if err := passwordhash.ValidateCost(pwd); err != nil {
				return err
			}
		} else {
			hashed, err := passwordhash.Hash(pwd)
			if err != nil {
				return fmt.Errorf("failed to hash password: %w", err)
			}
			data[constants.FieldPassword] = string(hashed)
		}
		return nil
	}
	// Placeholder: bcrypt of a fresh UUIDv4. Unique per row, unguessable,
	// matches the same rand->hex->bcrypt idiom used by the platform-pack
	// admin seed (controlplane/packs/platform_policy.go).
	placeholder, err := passwordhash.Hash(utils.GenerateID())
	if err != nil {
		return fmt.Errorf("seed placeholder password: %w", err)
	}
	data[constants.FieldPassword] = string(placeholder)
	return nil
}
