#' Aitken Transformation for Neutrosophic Interval Data
#'
#' Applies an Aitken variance-stabilizing transformation to interval-valued
#' observations using group-specific interval MSE values.
#'
#' @param Lower_y Numeric matrix of lower interval bounds.
#' @param Upper_y Numeric matrix of upper interval bounds.
#' @param group Vector identifying the group/year for every row of the input.
#' @param MSE_lower Numeric vector of lower MSE bounds, one per group.
#' @param MSE_upper Numeric vector of upper MSE bounds, one per group.
#'
#' @return A list containing transformed lower/upper matrices and their
#'   determinate and indeterminate components.
#'
#' @examples
#' Lower_y <- matrix(
#'   c(8.2, 5.1,
#'     7.9, 5.4,
#'     9.0, 6.2,
#'     8.8, 6.0,
#'     7.5, 4.8,
#'     7.8, 5.0,
#'     8.6, 5.8,
#'     8.4, 5.6),
#'   ncol = 2,
#'   byrow = TRUE
#' )
#'
#' Upper_y <- matrix(
#'   c(8.8, 5.7,
#'     8.5, 6.0,
#'     9.6, 6.8,
#'     9.4, 6.6,
#'     8.1, 5.4,
#'     8.4, 5.6,
#'     9.2, 6.4,
#'     9.0, 6.2),
#'   ncol = 2,
#'   byrow = TRUE
#' )
#'
#' group <- rep(1:4, each = 2)
#'
#' transformed <- nsAitkenTransform(
#'   Lower_y = Lower_y,
#'   Upper_y = Upper_y,
#'   group = group,
#'   MSE_lower = c(29.83, 16.30, 21.21, 3.62),
#'   MSE_upper = c(30.02, 16.43, 21.24, 3.89)
#' )
#'
#' transformed$weights
#' @export

nsAitkenTransform <- function(Lower_y, Upper_y, group,
                               MSE_lower, MSE_upper) {

  stopifnot(
    is.matrix(Lower_y),
    is.matrix(Upper_y),
    identical(dim(Lower_y), dim(Upper_y)),
    length(group) == nrow(Lower_y)
  )

  if (any(Lower_y > Upper_y)) {
    stop("Each value in Lower_y must be less than or equal to Upper_y.")
  }

  group <- factor(group)
  g <- nlevels(group)

  if (length(MSE_lower) != g || length(MSE_upper) != g) {
    stop("MSE_lower and MSE_upper must each contain one value per group.")
  }

  # Makes the code robust when supplied MSE interval bounds are reversed
  mse_L <- pmin(MSE_lower, MSE_upper)
  mse_U <- pmax(MSE_lower, MSE_upper)

  if (any(mse_L <= 0)) {
    stop("All MSE values must be positive.")
  }

  # Since 1 / sqrt(MSE) is decreasing, transformed weight bounds reverse.
  wt_L <- 1 / sqrt(mse_U)
  wt_U <- 1 / sqrt(mse_L)

  wt_d <- (wt_L + wt_U) / 2
  wt_i <- abs(wt_U - wt_L) / 2

  d_y <- (Lower_y + Upper_y) / 2
  i_y <- abs(Upper_y - Lower_y) / 2

  transformed_data_l <- matrix(
    NA_real_, nrow = nrow(Lower_y), ncol = ncol(Lower_y)
  )
  transformed_data_u <- transformed_data_l

  for (j in seq_len(g)) {
    rows <- which(group == levels(group)[j])

    # Retains your determinate/indeterminate interval arithmetic
    transformed_data_l[rows, ] <- d_y[rows, ] * wt_d[j]

    transformed_data_u[rows, ] <- transformed_data_l[rows, ] +
      d_y[rows, ] * wt_i[j] +
      i_y[rows, ] * wt_d[j] +
      i_y[rows, ] * wt_i[j]
  }

  transform_d <- (transformed_data_l + transformed_data_u) / 2
  transform_i <- abs(transformed_data_u - transformed_data_l) / 2

  list(
    Lower_y = transformed_data_l,
    Upper_y = transformed_data_u,
    determinate = transform_d,
    indeterminate = transform_i,
    weights = data.frame(
      Group = levels(group),
      MSE_lower = mse_L,
      MSE_upper = mse_U,
      Weight_lower = wt_L,
      Weight_upper = wt_U
    )
  )
}


