#' Corrected heterogeneity measure
#'
#' Internal helper for `method = "i2c"`. The intended implementation uses the
#' row of `pI2sim` corresponding to the observed `I2hat`.
#'
#' @keywords internal
aedl_i2c <- function(I2hat, vi, sig2t, I2_grid = seq(0, 0.99, by = 0.01),
                     a = 0, b = 1, nsim = 10000) {
  h_I2 <- I2_grid[2] - I2_grid[1]

  pI2sim <- sapply(
    I2_grid,
    aedl_pI2_given_I2,
    vi = vi,
    sig2t = sig2t,
    I2_grid = I2_grid,
    nsim = nsim
  )

  jhat <- floor(I2hat / h_I2) + 1
  jhat <- max(1, min(jhat, length(I2_grid)))

  lik_I2 <- pI2sim[jhat, ]
  prior_I2 <- stats::dunif(I2_grid, min = a, max = b)
  denom <- sum(prior_I2 * lik_I2)

  I2c <- sum(pmax(I2hat, I2_grid) * prior_I2 * lik_I2) / denom

  if (is.nan(I2c) || is.na(I2c)) {
    I2c <- I2hat
  }

  I2c <- min(I2c, 0.999999)
  tau2c <- sig2t * I2c / (1 - I2c)

  list(
    I2c = I2c,
    tau2c = tau2c,
    pI2sim = pI2sim,
    lik_I2 = lik_I2,
    prior_I2 = prior_I2,
    jhat = jhat
  )
}

#' Simulate p(I2hat | I2)
#'
#' @keywords internal
aedl_pI2_given_I2 <- function(I2, vi, sig2t, I2_grid, nsim = 10000) {
  K <- length(vi)
  h <- I2_grid[2] - I2_grid[1]

  s1 <- sum(1 / vi)
  s2 <- sum(1 / vi^2)
  denom <- s1 - s2 / s1

  tau2sim <- sig2t * I2 / (1 - I2)

  thetahat <- matrix(
    stats::rnorm(
      nsim * K,
      mean = 0,
      sd = rep(sqrt(vi + tau2sim), each = nsim)
    ),
    nrow = nsim,
    ncol = K
  )

  thetabari <- as.vector(thetahat %*% (1 / vi) / s1)

  centered <- sweep(thetahat, 1, thetabari, "-")
  Qi <- rowSums(sweep(centered^2, 2, vi, "/"))

  tau2dl0i <- (Qi - (K - 1)) / denom
  tau2dli <- pmax(0, tau2dl0i)

  I2dli <- tau2dli / (sig2t + tau2dli)
  I2dli <- floor(I2dli / h) * h
  I2dli <- pmin(pmax(I2dli, 0), max(I2_grid))

  PI2 <- stats::ecdf(I2dli)

  pI2 <- (PI2(I2_grid + h) - PI2(I2_grid)) / h
  pI2[1] <- (1 - sum(pI2[-1]) * h) / h

  pI2
}
