#' Perform A Comparative Evaluation of Dimension Reduction: SMFPCA versus MFPCA in Multivariate Spatial Data Reconstruction
#'
#' To assess the effectiveness of integrating the spatial and multivariate aspects through SMFPCA, it is
#' common to reconstruct the original functional data from the already computed scores and filters.
#' For each instance, we employ both the novel SMFPCA and the conventional MFPCA. We assess the
#' effectiveness of dimension reduction using the metric known as the normalized mean squared
#' error (NMSE) for each univariate component. NMSE* evaluates the quality of the approximation without being
#' influenced by grid boundary effects, unlike NMSE, where the approximation is
#' less accurate at the boundary.
#' @param Xspec an object of class SM_object, this function is obtained by applying the mfsd
#'  function with a non-zero value of q.
#' @param Xspecc an object of class M_object, this object is obtained by applying the mfsd
#'  function with q equal to zero.
#' @param X00 a list containing the functional spatial data. Either an fd object or an array.
#' @param Npc the number of multivariat spatial functional principal components to be computed.
#' @return a display of the NMSE and NMSE* results from \code{\link{print}}.
#' @keywords mfsd
#' @export

mfsd.evaluation = function (Xspec, Xspecc, X00, Npc = 3 )
{


  if (!inherits(Xspec, "M_object")) {
    stop("'Xspec' is not a M_object type.")
  }

  if (!inherits(Xspecc, "SM_object")) {
    stop("'Xspec' is not a SM_object type.")
  }


  if (!is.numeric(Npc)) {
    stop("Parameter Npc must be integer")
  }

  y <- length(Xspec$SM_Scores)
  for (j in 1:y) {
    if (!inherits(X00[[j]], "fsd.fd")) {
      stop("'X00' is not a fsd.fd type.")
    } }

  X = X00
  Npc = Npc


  for (j in 1:y) {

    paste("variable", j)

    X = X00[[j]]

    suppressMessages({

      Xstat.r = lapply(1:Npc,
                       function(k) {fsd.spca.inverse(Xspec[["filter"]][[j]],
                                                     Xspec[["SM_Scores"]][[j]][1:k,,,
                                                                               drop = FALSE],
                                                     Xspec[["SML_Mean"]][[j]])})

      Xspec.r = lapply(1:Npc,
                       function(k) {fsd.spca.inverse(Xspecc[["filter"]][[j]],
                                                     Xspecc[["SM_Scores"]][[j]][1:k,,,
                                                                                drop = FALSE], Xspecc[["SML_Mean"]][[j]])})

    })


    norm.st = sapply(Xstat.r, function(Xr) {fsd.norm(Xr - X)^2},
                     simplify = FALSE)
    norm.sp = sapply(Xspec.r, function(Xr) {fsd.norm(Xr - X)^2},
                     simplify = FALSE)


    mse.stat = sapply(norm.st, mean)
    mse.spec = sapply(norm.sp, mean)
    normX = mean(fsd.norm(X)^2)


    message(rbind("ADVANTAGE" = (mse.stat-mse.spec) / normX,
                "NMSE_spat" = mse.spec / normX,
                "NMSE_ord"  = mse.stat / normX,
                "NMSE_spat*"= 1 - cumsum(Xspecc[["SM_FSD"]][[j]][["var"]][1:Npc]), # aproximation error N2
                "NMSE_ord*" = 1 - cumsum(Xspec[["SM_FSD"]][[j]][["var"]][1:Npc])))


  }
}
