#' Neutrosophic Analysis of Variance for Randomized Complete Block Design
#'
#' Performs Neutrosophic Analysis of Variance (NANOVA) for interval-valued
#' response data from a Randomized Complete Block Design (RCBD).
#'
#' @param Lower_y Numeric matrix of lower bounds of the response variable.
#' @param Upper_y Numeric matrix of upper bounds of the response variable.
#' @param design Numeric matrix representing the RCBD layout.
#' @param alpha Significance level for interval-based LSD test. Default is 0.05.
#' @param verbose Logical. If \code{TRUE}, prints the NANOVA table and LSD comparisons.
#'
#' @return A list containing the Neutrosophic ANOVA table, interval-based LSD
#' comparisons (if applicable), and the interval LSD.
#'
#' @examples
#' Lower_y <- matrix(c(
#'   120.230,125.488,132.987,127.086,127.672,128.013,
#'   122.594,121.009,123.969,120.358,120.424,122.197,
#'   121.183,130.671,128.794,114.863,122.595,122.073,
#'   127.620,124.532,132.893,125.528,125.850,127.550
#' ), nrow = 4, byrow = TRUE)
#'
#' Upper_y <- matrix(c(
#'   127.6967536,131.2116955,141.2127373,136.1540904,130.6884772,136.8474149,
#'   129.8264289,130.3314544,133.3113414,126.5063118,128.4362999,130.2714433,
#'   124.5068016,139.3287297,134.1060197,124.2774447,127.2248520,130.3948469,
#'   131.0638721,129.8884785,135.5666716,127.7580663,132.0178679,133.3903886
#' ), nrow = 4, byrow = TRUE)
#'
#' design <- matrix(c(
#'   1,2,3,4,5,6,
#'   1,2,3,4,5,6,
#'   1,2,3,4,5,6,
#'   1,2,3,4,5,6
#' ), nrow = 4, byrow = TRUE)
#'
#' RCBDnsANOVA(Lower_y, Upper_y, design)
#'
#' @importFrom MASS ginv
#' @importFrom stats qf qt
#' @export



RCBDnsANOVA <- function(Lower_y, Upper_y,
                        design,
                        alpha = 0.05,
                        verbose = FALSE){

  #-------------------------------------------------------
  # Input Validation and Initialization
  #-------------------------------------------------------

  Lower_y <- as.matrix(Lower_y)
  Upper_y <- as.matrix(Upper_y)
  design  <- as.matrix(design)

  v <- max(design)
  b <- nrow(design)
  k <- ncol(design)

  rep_counts <- table(design)
  r <- unique(rep_counts)

  interval <- function(L, U){
    list(
      d = (L + U)/2,
      i = abs(U - L)/2
    )
  }

  n <- b * k

  #-------------------------------------------------------
  # Construction of Experimental Design and Model Matrices
  #-------------------------------------------------------

  trt_vec <- as.vector(t(design))

  Tmat <- matrix(0, n, v)

  for(i in 1:n){
    Tmat[i, trt_vec[i]] <- 1
  }

  mu <- matrix(1, n, 1)

  rep_vec <- rep(1:r, each = b/r * k)

  Rmat <- matrix(0, n, r)

  for(i in 1:n){
    Rmat[i, rep_vec[i]] <- 1
  }

  X <- cbind(Tmat, mu, Rmat)

  #-------------------------------------------------------
  # Interval Decomposition of Responses
  #-------------------------------------------------------

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

  dy <- as.vector(t(d_y))
  iy <- as.vector(t(i_y))

  #-------------------------------------------------------
  # Computation of Overall Interval Means and
  # Centered Interval Responses
  #-------------------------------------------------------

  ybar_l <- mean(Lower_y)
  ybar_u <- mean(Upper_y)
  ybar_d <- mean(d_y)
  ybar_i <- mean(i_y)

  yminusbar_l <- d_y - ybar_d
  yminusbar_u <- yminusbar_l + i_y - ybar_i

  yminusbar_d <- (yminusbar_l + yminusbar_u)/2
  yminusbar_i <- abs(yminusbar_u - yminusbar_l)/2

  yminusbar_sq_l <- yminusbar_d * yminusbar_d

  yminusbar_sq_u <- yminusbar_sq_l +
    2 * yminusbar_d * yminusbar_i +
    yminusbar_i * yminusbar_i

  yminusbar_sq_d <- (yminusbar_sq_l + yminusbar_sq_u)/2
  yminusbar_sq_i <- abs(yminusbar_sq_u - yminusbar_sq_l)/2

  #-------------------------------------------------------
  # Computation of Total Interval Sum of Squares
  #-------------------------------------------------------

  toss_l <- sum(yminusbar_sq_l)
  toss_u <- sum(yminusbar_sq_u)
  toss_d <- sum(yminusbar_sq_d)
  toss_i <- abs(toss_l - toss_u)/2


  #-------------------------------------------------------
  # Estimation of Adjusted Treatment Effects
  #-------------------------------------------------------

  Z <- cbind(mu, Rmat)

  M <- diag(nrow(X)) - Z %*% MASS::ginv(t(Z) %*% Z) %*% t(Z)

  Ct_adj <- t(Tmat) %*% M %*% Tmat

  bcdy_t_ad_d <- t(Tmat) %*% cbind(mu, Rmat) %*%
    MASS::ginv(t(cbind(mu, Rmat)) %*% cbind(mu, Rmat)) %*%
    t(cbind(mu, Rmat)) %*% dy

  bcdy_t_ad_i <- t(Tmat) %*% cbind(mu, Rmat) %*%
    MASS::ginv(t(cbind(mu, Rmat)) %*% cbind(mu, Rmat)) %*%
    t(cbind(mu, Rmat)) %*% iy

  Qy_ad_l <- t(Tmat) %*% dy - bcdy_t_ad_d

  Qy_ad_u <- Qy_ad_l[(1:v), ] +
    t(Tmat) %*% iy - bcdy_t_ad_i

  Qy_t_ad_d <- (Qy_ad_l + Qy_ad_u)/2
  Qy_t_ad_i <- abs(Qy_ad_l - Qy_ad_u)/2

  ay_t_ad_l <- MASS::ginv(Ct_adj) %*% Qy_t_ad_d

  ay_t_ad_u <- ay_t_ad_l + Qy_t_ad_i/b

  ay_t_ad_d <- (ay_t_ad_l + ay_t_ad_u)/2
  ay_t_ad_i <- abs(ay_t_ad_l - ay_t_ad_u)/2

  #-------------------------------------------------------
  # Estimation of Adjusted Block Effects
  #-------------------------------------------------------

  Z <- cbind(mu, Tmat)

  M <- diag(nrow(X)) - Z %*% MASS::ginv(t(Z) %*% Z) %*% t(Z)

  Cb_adj <- t(Rmat) %*% M %*% Rmat

  bcdy_b_ad_d <- t(Rmat) %*% cbind(mu, Tmat) %*%
    MASS::ginv(t(cbind(mu, Tmat)) %*% cbind(mu, Tmat)) %*%
    t(cbind(mu, Tmat)) %*% dy

  bcdy_b_ad_i <- t(Rmat) %*% cbind(mu, Tmat) %*%
    MASS::ginv(t(cbind(mu, Tmat)) %*% cbind(mu, Tmat)) %*%
    t(cbind(mu, Tmat)) %*% iy

  Qy_ad_l <- t(Rmat) %*% dy - bcdy_b_ad_d

  Qy_ad_u <- Qy_ad_l[(1:b), ] +
    t(Rmat) %*% iy - bcdy_b_ad_i

  Qy_b_ad_d <- (Qy_ad_l + Qy_ad_u)/2
  Qy_b_ad_i <- abs(Qy_ad_l - Qy_ad_u)/2

  ay_b_ad_l <- MASS::ginv(Cb_adj) %*% Qy_b_ad_d

  ay_b_ad_u <- ay_b_ad_l + Qy_b_ad_i/v

  ay_b_ad_d <- (ay_b_ad_l + ay_b_ad_u)/2
  ay_b_ad_i <- abs(ay_b_ad_l - ay_b_ad_u)/2

  #-------------------------------------------------------
  # Computation of Interval Sums of Squares
  #-------------------------------------------------------

  ss_t_ad_l <- sum(Qy_t_ad_d * ay_t_ad_d)

  ss_t_ad_u <- ss_t_ad_l +
    sum(Qy_t_ad_d * ay_t_ad_i +
          Qy_t_ad_i * ay_t_ad_d +
          Qy_t_ad_i * ay_t_ad_i)

  ss_t_ad_d <- (ss_t_ad_l + ss_t_ad_u)/2
  ss_t_ad_i <- abs(ss_t_ad_u - ss_t_ad_l)/2

  ss_b_ad_l <- sum(Qy_b_ad_d * ay_b_ad_d)

  ss_b_ad_u <- ss_b_ad_l +
    sum(Qy_b_ad_d * ay_b_ad_i +
          Qy_b_ad_i * ay_b_ad_d +
          Qy_b_ad_i * ay_b_ad_i)

  ss_b_ad_d <- (ss_b_ad_l + ss_b_ad_u)/2
  ss_b_ad_i <- abs(ss_b_ad_u - ss_b_ad_l)/2

  mdss_all_ad_l <- ss_t_ad_d + ss_b_ad_d

  mdss_all_ad_u <- mdss_all_ad_l +
    ss_t_ad_i + ss_b_ad_i

  mdss_all_ad_d <- (mdss_all_ad_u + mdss_all_ad_l)/2
  mdss_all_ad_i <- abs(mdss_all_ad_u - mdss_all_ad_l)/2

  ess_all_ad_l <- toss_d - mdss_all_ad_d

  ess_all_ad_u <- ess_all_ad_l +
    toss_i - mdss_all_ad_i

  ess_all_ad_d <- (ess_all_ad_l + ess_all_ad_u)/2
  ess_all_ad_i <- abs(ess_all_ad_u - ess_all_ad_l)/2

  #-------------------------------------------------------
  # Computation of Interval Mean Squares and F-Statistics
  #-------------------------------------------------------

  SV <- c("Treatment", "Replication", "Error", "Total")

  DF <- c(v - 1, b - 1, (v - 1) * (b - 1), n - 1)

  SSN <- list(
    c(ss_t_ad_l, ss_t_ad_u),
    c(ss_b_ad_l, ss_b_ad_u),
    c(ess_all_ad_l, ess_all_ad_u),
    c(toss_l, toss_u)
  )

  MSSN <- list(
    c(ss_t_ad_l/(v - 1), ss_t_ad_u/(v - 1)),
    c(ss_b_ad_l/(b - 1), ss_b_ad_u/(b - 1)),
    c(ess_all_ad_l/((v - 1) * (b - 1)),
      ess_all_ad_u/((v - 1) * (b - 1))),
    c(NA, NA)
  )

  F_t_ad_L <- (ss_t_ad_d/(v - 1)) /
    (ess_all_ad_d/((v - 1) * (b - 1)))

  F_t_ad_U <- F_t_ad_L +
    (((ss_t_ad_d/(v - 1)) *
        (ess_all_ad_i/((v - 1) * (b - 1)))) +
       ((ss_t_ad_i/(v - 1)) *
          (ess_all_ad_d/((v - 1) * (b - 1)))) +
       ((ss_t_ad_i/(v - 1)) *
          (ess_all_ad_i/((v - 1) * (b - 1))))) /
    ((ess_all_ad_d/((v - 1) * (b - 1))) *
       (ess_all_ad_d/((v - 1) * (b - 1))))

  F_b_ad_L <- (ss_b_ad_d/(b - 1)) /
    (ess_all_ad_d/((v - 1) * (b - 1)))

  F_b_ad_U <- F_b_ad_L +
    (((ss_b_ad_d/(b - 1)) *
        (ess_all_ad_i/((v - 1) * (b - 1)))) +
       ((ss_b_ad_i/(b - 1)) *
          (ess_all_ad_d/((v - 1) * (b - 1)))) +
       ((ss_b_ad_i/(b - 1)) *
          (ess_all_ad_i/((v - 1) * (b - 1))))) /
    ((ess_all_ad_d/((v - 1) * (b - 1))) *
       (ess_all_ad_d/((v - 1) * (b - 1))))

  FN <- list(
    c(F_t_ad_L, F_t_ad_U),
    c(F_b_ad_L, F_b_ad_U),
    c(NA, NA),
    c(NA, NA)
  )

  format_interval <- function(x){
    if(any(is.na(x))) return("")
    paste0("[", round(x[1], 2), ", ", round(x[2], 2), "]")
  }

  SSN_fmt <- sapply(SSN, format_interval)
  MSSN_fmt <- sapply(MSSN, format_interval)
  FN_fmt <- sapply(FN, format_interval)

  nanova_table <- data.frame(
    SV = SV,
    DF = DF,
    SSN = SSN_fmt,
    MSSN = MSSN_fmt,
    FN = FN_fmt,
    stringsAsFactors = FALSE
  )
  #-------------------------------------------------------
  # Determination of Significance
  #-------------------------------------------------------

  Ftab5_t   <- qf(0.95, v-1, (v-1)*(b-1))
  Ftab1_t   <- qf(0.99, v-1, (v-1)*(b-1))
  Ftab001_t <- qf(0.999, v-1, (v-1)*(b-1))

  trt_significance <- ifelse(
    F_t_ad_L > Ftab001_t, "***",
    ifelse(
      F_t_ad_L > Ftab1_t, "**",
      ifelse(
        F_t_ad_L > Ftab5_t, "*", "NS"
      )
    )
  )

  Ftab5_b   <- qf(0.95, b-1, (v-1)*(b-1))
  Ftab1_b   <- qf(0.99, b-1, (v-1)*(b-1))
  Ftab001_b <- qf(0.999, b-1, (v-1)*(b-1))

  rep_significance <- ifelse(
    F_b_ad_L > Ftab001_b, "***",
    ifelse(
      F_b_ad_L > Ftab1_b, "**",
      ifelse(
        F_b_ad_L > Ftab5_b, "*", "NS"
      )
    )
  )

  nanova_table$Significance <- c(
    trt_significance,
    rep_significance,
    "",
    ""
  )

  #-------------------------------------------------------
  # Interval-Based LSD Analysis
  #-------------------------------------------------------

  if(trt_significance != "NS"){

    dfe <- (v-1)*(b-1)

    MSE_d <- ess_all_ad_d/dfe
    MSE_i <- ess_all_ad_i/dfe

    SEd_d <- sqrt((2*MSE_d)/r)
    SEd_i <- sqrt((2*MSE_i)/r)

    tval <- qt(1-alpha/2,dfe)

    LSD_l <- tval*SEd_d
    LSD_u <- LSD_l+tval*SEd_i

    grand_mean <- mean(dy)

    adjmeans_d <- grand_mean + as.vector(ay_t_ad_d)
    adjmeans_i <- as.vector(ay_t_ad_i)

    comparison <- data.frame()

    for(i in 1:(v-1)){

      for(j in (i+1):v){

        Diff_l <- abs(adjmeans_d[i]-adjmeans_d[j])
        Diff_u <- Diff_l + adjmeans_i[i] + adjmeans_i[j]

        Lower <- min(Diff_l,Diff_u)
        Upper <- max(Diff_l,Diff_u)

        if(Upper < LSD_l){

          Result <- "NS"

        }else if(Lower > LSD_u){

          Result <- "S"

        }else{

          Result <- "ID"

        }

        comparison <- rbind(
          comparison,
          data.frame(
            Treatment1=i,
            Treatment2=j,
            Difference=paste0("[",round(Lower,2),", ",round(Upper,2),"]"),
            LSD=paste0("[",round(LSD_l,2),", ",round(LSD_u,2),"]"),
            Result=Result,
            stringsAsFactors=FALSE
          )
        )

      }

    }

  }else{

    comparison <- NULL
    LSD_l <- NULL
    LSD_u <- NULL

  }

  #-------------------------------------------------------
  # Display Results
  #-------------------------------------------------------

  if(verbose){

    cat("\nNeutrosophic Analysis of Variance Table\n")
    print(nanova_table,row.names=FALSE)

    if(trt_significance != "NS"){

      cat("\nTreatment effect is significant. Hence multiple comparison using LSD is performed.\n")

      message("\nLSD Interval : [",
              round(LSD_l,4),
              ", ",
              round(LSD_u,4),
              "]")

      cat("\nTreatment Comparisons Using LSD\n")
      print(comparison,row.names=FALSE)

    }else{

      cat("\nTreatment effect is non significant. Hence multiple comparison is not performed.\n")

    }

    message("\nSignificance Codes:")
    message("*** : Significant at p < 0.001")
    message("**  : Significant at p < 0.01")
    message("*   : Significant at p < 0.05")
    message("NS  : Non Significant")
    message("ID  : Indeterminate")

  }

  #-------------------------------------------------------
  # Return Results
  #-------------------------------------------------------

  invisible(list(
    nanova_table = nanova_table,
    comparison = comparison,
    LSD = if(!is.null(LSD_l))
      c(Lower=LSD_l,Upper=LSD_u)
    else NULL
  ))
}

