#' Random graphical model estimation under L0-penalty
#'
#' Estimates sparse precision matrices from a covariance matrix using
#' an iterative sparse-step approximation under an L0-style penalty.
#' The method evaluates a grid of theta values and returns both
#' continuous and binary precision matrices representing the inferred
#' network structure.
#'
#' @param S A numeric covariance matrix.
#' @param theta.jump Step size for candidate theta values.
#' @param n.iter Number of inner iterations.
#' @param gamma0 Initial gamma value.
#' @param gammastop Stopping value for gamma.
#' @param IMsteps Currently unused.
#' @param gammastep Factor used to decrease gamma.
#' @param force.zero Logical flag (currently unused).
#' @param threshold Threshold for binarizing the precision matrix.
#' @param use_diag Logical flag (currently unused).
#'
#' @return A list where each element contains:
#' \describe{
#'   \item{precision_matrix}{Estimated precision matrix.}
#'   \item{binary_precision_matrix}{Thresholded binary matrix.}
#'   \item{theta}{Theta value used.}
#'   \item{sample_index}{Index of theta.}
#' }
#'
#' @examples
#' S <- diag(3)
#' out <- rgml0(S, theta.jump = 0.4, n.iter = 1,
#'              gamma0 = 1, gammastop = 0.1, gammastep = 2)
#' length(out)
#'
#' @export
rgml0 <- function(S, theta.jump = 0.1, n.iter = 5, gamma0 = 1e3,
                  gammastop = 1e-4, IMsteps = 2, gammastep = 1.1,
                  force.zero = TRUE, threshold = 1e-7,
                  use_diag = FALSE) {

  theta_candidate <- seq(0.01, 0.91, by = theta.jump)
  results <- list()
  p <- ncol(S)

  for (sample_index in seq_along(theta_candidate)) {
    theta <- theta_candidate[sample_index]
    lambda <- -log(theta / (1 - theta))

    G <- matrix(1, ncol = p, nrow = p)
    diag(G) <- 0

    B <- tryCatch(
      solve(S + lambda * G + diag(1e-6, p)),
      error = function(e) diag(1, p)
    )

    gamma <- gamma0

    while (gamma > gammastop) {
      for (k in seq_len(n.iter)) {
        for (j in seq_len(p)) {

          b <- B[-j, j]

          est.precision.vec <- 1 / (b^2 + gamma^2)
          est.precision <- diag(as.vector(est.precision.vec), p - 1, p - 1)

          A <- S[j, j] * diag(rep(1, p - 1)) +
            lambda * B[-j, -j] %*% est.precision +
            diag(1e-6, p - 1)

          a <- -B[-j, -j] %*% S[-j, j]

          b <- tryCatch(
            solve(A, a),
            error = function(e) MASS::ginv(A) %*% a
          )

          b0 <- (1 - crossprod(S[-j, j] +
                                 lambda * est.precision %*% b, b)[1]) / S[j, j]

          B[-j, j] <- b
          B[j, -j] <- b
          B[j, j] <- b0
        }
      }

      gamma <- gamma / gammastep
    }

    B_binary <- B
    B_binary[abs(B) < threshold] <- 0
    B_binary[abs(B) > threshold] <- 1
    diag(B_binary) <- 0

    results[[sample_index]] <- list(
      precision_matrix = B,
      binary_precision_matrix = B_binary,
      theta = theta,
      sample_index = sample_index
    )
  }

  results
}