#' Gradient of the phase-function estimating equations
#'
#' Computes the gradient of the phase-function estimating equations with
#' respect to the regression coefficients.
#'
#' @param beta Numeric vector of length \code{p + q} containing the regression
#'   coefficients.
#' @param S_y Numeric vector containing \code{sum_j sin(t * Y_j)} evaluated on
#'   the grid \code{t}.
#' @param C_y Numeric vector containing \code{sum_j cos(t * Y_j)} evaluated on
#'   the grid \code{t}.
#' @param WZ Numeric matrix of dimension \code{n x (p + q)} containing all
#'   covariates.
#' @param t Numeric vector giving the grid of frequency values.
#' @param estWeight Numeric vector of length \code{n} giving observation
#'   weights.
#'
#' @return Numeric vector of length \code{p + q} containing the phase-function
#'   gradient evaluated at \code{beta}.
#'
#'
#'
#'
#'@keywords internal

PhaseGradient <- function(beta, S_y, C_y, WZ, t, estWeight) {
  # beta      : (p+q) × 1 coefficient vector
  # S_y       : vector of sum_j sin(t Y_j), length = length(t)
  # C_y       : vector of sum_j cos(t Y_j), length = length(t)
  # WZ        : n × (p+q) matrix of covariates
  # t         : grid of t values
  # estWeight : length-n vector of observation weights

  n <- nrow(WZ)
  p_tot <- length(beta)

  tDist <- t[2] - t[1]

  # kernel weights
  kernel <- omega(t / max(t), type = "quadratic")

  # trig arguments
  tvec <- matrix(t, nrow = n, ncol = length(t), byrow = TRUE)
  linpred <- as.vector(WZ %*% beta)
  trigArg <- linpred * tvec

  S <- sin(trigArg)
  C <- cos(trigArg)

  # weights
  estWeight <- as.vector(estWeight)
  Q <- matrix(estWeight, nrow = n, ncol = length(t))

  QC <- Q * C
  QS <- Q * S

  grad <- numeric(p_tot)

  # Gradient computation
  for (dimIndex in seq_len(p_tot)) {

    dimFactor <- WZ[, dimIndex] * tvec

    outer <- colSums(QC) * S_y - colSums(QS) * C_y

    inner <- -(colSums(dimFactor * QS) * S_y) -
      (colSums(dimFactor * QC) * C_y)

    integrand <- outer * inner * kernel * tDist

    grad[dimIndex] <- 2 * sum(integrand)
  }

  grad / n
}
