#' @title Infinitesimal Generator, Drift, and Diffusion Functions
#' @description Computes discrete drift b_N(y, tau) and diffusion a_N(y, tau) operators.
#' @param y Numeric. Scaled fuzzy state y in [0, 1].
#' @param weights Vector. Unobserved element weights.
#' @param mu_unobserved Vector. Fuzzy membership values for unobserved elements.
#' @return List containing drift `b` and diffusion `a`.
#' @export
fuzzyurn_generator <- function(y, weights, mu_unobserved) {
  Omega <- sum(weights)
  b_N <- sum(mu_unobserved * (weights / Omega))
  a_N <- sum((mu_unobserved^2) * (weights / Omega))
  
  return(list(drift = b_N, diffusion = a_N))
}

#' @title Diffusion Limit SDE Simulator
#' @description Simulates continuous Itô Diffusion Limit process dY(tau).
#' @param N Integer. Total population size.
#' @param y0 Numeric. Initial state y(0).
#' @param T_max Numeric. Time horizon.
#' @param steps Integer. Number of Euler-Maruyama discretization steps.
#' @param drift_fn Function b(y, tau).
#' @param diff_fn Function a(y, tau).
#' @return Data frame with time `tau` and continuous trajectory `Y`.
#' @importFrom stats rnorm
#' @export
fuzzyurn_sde <- function(N, y0, T_max = 1.0, steps = 1000, drift_fn, diff_fn) {
  dt <- T_max / steps
  tau <- seq(0, T_max, length.out = steps + 1)
  Y <- numeric(steps + 1)
  Y[1] <- y0
  
  for (i in 1:steps) {
    y_curr <- Y[i]
    t_curr <- tau[i]
    
    b_val <- drift_fn(y_curr, t_curr)
    a_val <- max(0, diff_fn(y_curr, t_curr))
    
    dW <- rnorm(1, mean = 0, sd = sqrt(dt))
    Y[i + 1] <- y_curr + b_val * dt + (1 / sqrt(N)) * sqrt(a_val) * dW
  }
  
  return(data.frame(tau = tau, Y = Y))
}
