#' Neutrosophic Levene's Test for Interval-Valued Data
#'
#' Tests homogeneity of variances for interval-valued observations using
#' neutrosophic lower and upper test-statistic bounds.
#'
#' @param Lower_y Numeric matrix of lower interval bounds.
#' @param Upper_y Numeric matrix of upper interval bounds; same dimensions as
#'   `Lower_y`.
#' @param design Treatment-design matrix. Treatment labels in each row must be
#'   arranged in consecutive year blocks.
#' @param alpha Significance level. Default is `0.05`.
#' @param verbose Logical; print the test table when `TRUE`.
#'
#' @return An invisible list containing the Levene statistic interval,
#'   critical F value, homogeneity decision, and ANOVA table.
#'
#'@importFrom MASS ginv
#' @importFrom stats qf qt model.matrix
#'
#'@examples
#' # Two replications, three treatments, and two years.
#' # Columns are ordered as:
#' # Year 1 (T1, T2, T3), Year 2 (T1, T2, T3).
#'
#' Lower_y <- matrix(c(
#'   10, 12, 11, 13, 14, 12,
#'    9, 11, 10, 12, 13, 11
#' ), nrow = 2, byrow = TRUE)
#'
#' Upper_y <- matrix(c(
#'   12, 14, 13, 15, 16, 14,
#'   11, 13, 12, 14, 15, 13
#' ), nrow = 2, byrow = TRUE)
#'
#' design <- matrix(c(
#'   1, 2, 3, 1, 2, 3,
#'   1, 2, 3, 1, 2, 3
#' ), nrow = 2, byrow = TRUE)
#'
#' levene_result <- nsLeveneTest(
#'   Lower_y = Lower_y,
#'   Upper_y = Upper_y,
#'   design = design,
#'   alpha = 0.05,
#'   verbose = TRUE
#' )
#'
#' levene_result$Homogeneity
#'
#' @importFrom MASS ginv
#' @export


nsLeveneTest <- function(Lower_y, Upper_y, design,
                        alpha = 0.05, verbose = TRUE) {

  stopifnot(
    is.matrix(Lower_y),
    is.matrix(Upper_y),
    is.matrix(design),
    identical(dim(Lower_y), dim(Upper_y)),
    identical(dim(Lower_y), dim(design)),
    alpha > 0, alpha < 1
  )

  # Design dimensions
  b <- nrow(design)                  # replications
  k <- ncol(design)                  # total columns
  v <- length(unique(as.vector(design)))  # treatments

  # Number of years = repetitions of each treatment in one design row
  treatment.counts <- table(design[1, ])

  if (length(unique(as.numeric(treatment.counts))) != 1) {
    stop("Each treatment must occur equally often in each row of 'design'.")
  }

  r <- as.integer(treatment.counts[1])  # years

  if (k != r * v) {
    stop("Columns must contain r consecutive year blocks, each with v treatments.")
  }

  N <- b * k

  if (N <= r) {
    stop("Insufficient observations: N must be greater than the number of years.")
  }

  # Determinate and indeterminate components
  datad <- (Lower_y + Upper_y) / 2
  datai <- abs(Upper_y - Lower_y) / 2

  # Year means: assumes columns are ordered year-by-year
  year.mean_d <- vapply(
    seq_len(r),
    function(j) {
      cols <- ((j - 1) * v + 1):(j * v)
      mean(datad[, cols, drop = FALSE])
    },
    numeric(1)
  )

  year.mean_i <- vapply(
    seq_len(r),
    function(j) {
      cols <- ((j - 1) * v + 1):(j * v)
      mean(datai[, cols, drop = FALSE])
    },
    numeric(1)
  )

  # Matrices of year means, aligned with Lower_y and Upper_y
  mean.mat_d <- matrix(
    rep(year.mean_d, each = b * v),
    nrow = b, ncol = k, byrow = FALSE
  )

  mean.mat_i <- matrix(
    rep(year.mean_i, each = b * v),
    nrow = b, ncol = k, byrow = FALSE
  )

  # Absolute deviations: retains your specified neutrosophic formulation
  zl <- abs(datad - mean.mat_d)
  zu <- zl + datai - mean.mat_i

  d_y <- (zl + zu) / 2
  i_y <- abs(zu - zl) / 2

  # Vectorization is column-wise, matching the year-block arrangement
  d <- as.vector(d_y)
  i <- as.vector(i_y)

  # Year membership design matrix: replaces undefined Xyear
  year <- factor(rep(seq_len(r), each = b * v))
  Xyear <- model.matrix(~ year - 1)

  PX <- Xyear %*% MASS::ginv(t(Xyear) %*% Xyear) %*% t(Xyear)

  J <- matrix(1, nrow = N, ncol = N)
  P1 <- J / N
  I <- diag(N)

  #-------------------------------------------------------
  # Between-year sum of squares
  #-------------------------------------------------------
  px1 <- PX - P1

  zdashpx1L <- t(d) %*% px1
  zdashpx1U <- zdashpx1L + t(i) %*% px1

  zdashpx1d <- (zdashpx1L + zdashpx1U) / 2
  zdashpx1i <- abs(zdashpx1U - zdashpx1L) / 2

  ssbL <- sum(zdashpx1d * d)
  ssbU <- ssbL +
    sum(zdashpx1i * d) +
    sum(zdashpx1d * i) +
    sum(zdashpx1i * i)

  ssbd <- (ssbL + ssbU) / 2
  ssbi <- abs(ssbU - ssbL) / 2

  mssbd <- ssbd / (r - 1)
  mssbi <- ssbi / (r - 1)

  #-------------------------------------------------------
  # Within-year sum of squares
  #-------------------------------------------------------
  p1x <- I - PX

  zdashp1xL <- t(d) %*% p1x
  zdashp1xU <- zdashp1xL + t(i) %*% p1x

  zdashp1xd <- (zdashp1xL + zdashp1xU) / 2
  zdashp1xi <- abs(zdashp1xU - zdashp1xL) / 2

  sswL <- sum(zdashp1xd * d)
  sswU <- sswL +
    sum(zdashp1xi * d) +
    sum(zdashp1xd * i) +
    sum(zdashp1xi * i)

  sswd <- (sswL + sswU) / 2
  sswi <- abs(sswU - sswL) / 2

  msswd <- sswd / (N - r)
  msswi <- sswi / (N - r)

  #-------------------------------------------------------
  # Neutrosophic Levene's statistic
  #-------------------------------------------------------
  WL <- mssbd / msswd

  WU <- WL +
    (mssbd * msswi + mssbi * msswd + mssbi * msswi) /
    (msswd * msswd)

  #-------------------------------------------------------
  # Homogeneity decision
  #-------------------------------------------------------
  F_critical <- stats::qf(
    1 - alpha,
    df1 = r - 1,
    df2 = N - r
  )

  Homogeneity <- if (WL > F_critical) {
    "Not Homogeneous"
  } else if (WU <= F_critical) {
    "Homogeneous"
  } else {
    "Indeterminate"
  }

  Levene.table <- data.frame(
    Source = c("Between Years", "Within Years"),
    DF = c(r - 1, N - r),
    `Neutrosophic Levene Statistic` = c(
      sprintf("[%.4f, %.4f]", WL, WU),
      "-"
    ),
    `F Critical` = c(sprintf("%.4f", F_critical), "-"),
    Decision = c(Homogeneity, "-"),
    check.names = FALSE
  )

  if (verbose) {
    cat("\n")
    cat("============================================================\n")
    cat("        NEUTROSOPHIC LEVENE'S TEST OF HOMOGENEITY\n")
    cat("============================================================\n\n")
    print(Levene.table, row.names = FALSE, right = FALSE)
    cat("\n")
  }

  invisible(list(
    Levene.table = Levene.table,
    Levene.Statistic = c(Lower = WL, Upper = WU),
    F.critical = F_critical,
    Homogeneity = Homogeneity,
    Years = r,
    Treatments = v,
    Replications = b
  ))
}

