#' fit_models
#' 
#' this helper function fits three models to a provided training dataset,
#' and returns a testing dataset with predictions based on each model.
#' 
#' the thre models are intercept-only; PRR; and a smooth gam fit. 
#'
#' @param train training df
#' @param test testing df
#'
#' @return testing df with predictions from each model
#' @export
#'
fit_models = function(train, test, resid = TRUE) {
	
	train = as_tibble(train)
	test = as_tibble(test)
	
	model_prop =  lm(delta_obs ~ 0 + fmii, data = train)
	model_null =  lm(y_obs ~ 1, data = train)
	# model_stan_reg = lm(y_obs ~ x, data = train)
	model_sm =    mgcv::gam(y_obs ~ s(x), data = train)
	model_exp =   nls(y_obs ~ a + r * (66 - a) * (1 - exp(-x / tau)), data = train, 
										algorithm = "port", control = list(maxiter = 10000, warnOnly = TRUE), 
										start = list(a = 30, r = 0.95, tau = 20), lower = c(0, 0, 0), upper = c(66, 1, Inf))
	model_const = fit_const(y_obs ~ x, data = train)
	
	test = 
		test %>% 
		add_predictions(model_prop, var = "pred_delta") %>% 
		mutate(pred_y_PRR = x + pred_delta) %>% 
		add_predictions(model_null, var = "pred_y_Int") %>% 
		# add_predictions(model_stan_reg, var = "pred_y_stan_reg") %>% 
		add_predictions(model_sm, var = "pred_y_GAM") %>% 
		add_predictions(model_exp, var = "pred_y_Exp") %>% 
		add_predictions(model_const, var = "pred_y_Const") %>% 
		mutate(
			resid_PRR = y_obs - pred_y_PRR,
			resid_Int = y_obs - pred_y_Int,
			# resid_Stan = y_obs - pred_y_stan_reg,
			resid_GAM =   y_obs - pred_y_GAM,
			resid_Exp =   y_obs - pred_y_Exp,
			resid_Const = y_obs - pred_y_Const
	) 
	
	# if (resid) { test = test %>% select(starts_with("resid_")) }
	# if (!resid) { test = test %>% select(starts_with("pred_y_"))}
	
	test
	
}