package user import ( "math" "time" ) // Activity level multipliers (Mifflin-St Jeor). var activityMultiplier = map[string]float64{ "low": 1.375, "moderate": 1.55, "high": 1.725, } // Goal adjustments in kcal. var goalAdjustment = map[string]float64{ "lose": -500, "maintain": 0, "gain": 300, } // AgeFromDOB computes age in years from a "YYYY-MM-DD" string. Returns nil on error. func AgeFromDOB(dob *string) *int { if dob == nil { return nil } t, err := time.Parse("2006-01-02", *dob) if err != nil { return nil } now := time.Now() years := now.Year() - t.Year() if now.Month() < t.Month() || (now.Month() == t.Month() && now.Day() < t.Day()) { years-- } return &years } // CalculateDailyCalories computes the daily calorie target using the // Mifflin-St Jeor equation. Returns nil if any required parameter is missing. func CalculateDailyCalories(heightCM *int, weightKG *float64, age *int, gender, activity, goal *string) *int { if heightCM == nil || weightKG == nil || age == nil || gender == nil || activity == nil || goal == nil { return nil } // BMR = 10 * weight(kg) + 6.25 * height(cm) - 5 * age bmr := 10**weightKG + 6.25*float64(*heightCM) - 5*float64(*age) switch *gender { case "male": bmr += 5 case "female": bmr -= 161 default: return nil } mult, ok := activityMultiplier[*activity] if !ok { return nil } adj, ok := goalAdjustment[*goal] if !ok { return nil } tdee := bmr * mult result := int(math.Round(tdee + adj)) return &result }