#' Compute Multivariate Dynamics Similarity Coefficient (MDSC)
#'
#' @param X Matrix or data.frame, each column is a component time series.
#' @param Y Matrix or data.frame, each column is a component time series.
#' @param n_s Integer, number of states.
#' @param lag Integer, lag order.
#' @param th_step Numeric, threshold step size.
#'
#' @return Numeric, MDSC value.
#' @export
#' @references
#' Nie, Chun-Xiao. "Distinguishing time series generated by different intrinsic dynamics using quantile graphs." Communications in Nonlinear Science and Numerical Simulation (2026): 110002.
#' @examples
#' X <- matrix(rnorm(3000), ncol = 3)
#' Y <- matrix(rnorm(3000), ncol = 3)
#' mdsc(X, Y, n_s = 10)
mdsc <- function(X, Y, n_s = 15, lag = 1, th_step = 0.005) {
  X <- as.matrix(X)
  Y <- as.matrix(Y)
  if (ncol(X) != ncol(Y)) stop("X and Y must have the same number of columns")
  k <- ncol(X)

  dsc_vals <- matrix(0, k, k)
  for (i in 1:k) {
    for (j in 1:k) {
      if (i == j) {
        Px <- transition_matrix(X[, i], n_s, lag)
        Py <- transition_matrix(Y[, j], n_s, lag)
      } else {
        Px <- cross_transition_matrix(X[, i], X[, j], n_s, lag)
        Py <- cross_transition_matrix(Y[, i], Y[, j], n_s, lag)
      }
      max_th <- 1 / n_s
      thresholds <- seq(0, max_th, by = th_step)
      jaccards <- vapply(thresholds, function(th) {
        Ax <- (Px > th) * 1      # strict inequality as requested
        Ay <- (Py > th) * 1
        inter <- sum(Ax & Ay)
        union <- sum(Ax | Ay)
        if (union == 0) 1 else inter / union
      }, numeric(1))
      dsc_vals[i, j] <- mean(jaccards)
    }
  }
  mean(dsc_vals)
}
