#' Confidence intervals for site-specific GEV parameters
#'
#' @name Site_parCI
#' @param atsite_temp
#' A numeric vector or single-column matrix of air temperature data.
#' @param model
#' A single integer from 1 to 4 defining the GEV model.
#' @param site_par
#' A 1-row, 5-column data.frame or matrix generated by Fit_model().
#' @param n.boots
#' Number of bootstrap replicates. Values smaller than 100 are not allowed.
#' Defaults to `999`.
#' @param progress
#' Logical scalar controlling whether a progress bar is displayed.
#' `TRUE` forces the bar on, `FALSE` forces it off, and
#' `NULL` (default) defers to `getOption("NSTempRFA.progress")`,
#' which itself falls back to `interactive()`. Set
#' `options(NSTempRFA.progress = FALSE)` to suppress the bar globally.
#'
#' @returns
#' A matrix containing the lower and upper 95% confidence limits of
#' the estimated parameters.
#'
#' @export
#' @importFrom stats quantile
#' @importFrom utils txtProgressBar setTxtProgressBar
#'
#' @examplesIf interactive()
#' temperatures <- TmaxCPC_SP$Pixel_1
#' model <- 2
#' site_par <- Fit_model(temperatures, model)
#'
#' Site_parCI(
#'   atsite_temp = temperatures,
#'   model       = model,
#'   site_par    = site_par[1, 1:5],
#'   n.boots     = 100
#' )
Site_parCI <- function(
  atsite_temp,
  model,
  site_par,
  n.boots = 999,
  progress = NULL
) {
  #----------------------------------------------------------
  # Input checks
  #----------------------------------------------------------
  check_model(model)
  check_n.boots(n.boots)
  data_site <- check_atsite_temp(atsite_temp)
  site_par <- check_site_par(site_par)
  max_time <- length(data_site)

  #----------------------------------------------------------
  # Time-varying parameters
  #----------------------------------------------------------
  time <- seq_len(max_time)
  par.temporal <- matrix(NA_real_, max_time, 3)
  par.temporal[, 1] <- site_par[1] + site_par[2] * time
  par.temporal[, 2] <- site_par[3] + site_par[4] * time
  par.temporal[, 3] <- site_par[5]

  if (any(par.temporal[, 2] <= 0)) {
    stop("The scale parameter becomes non-positive over time.", call. = FALSE)
  }

  #----------------------------------------------------------
  # Transform to Gumbel space
  #----------------------------------------------------------
  use_gumbel <- abs(site_par[5]) < sqrt(.Machine$double.eps)

  if (use_gumbel) {
    IDD.series <- (data_site - par.temporal[, 1]) / par.temporal[, 2]
  } else {
    z <- 1 +
      par.temporal[, 3] *
        ((data_site - par.temporal[, 1]) / par.temporal[, 2])
    if (any(z <= 0, na.rm = TRUE)) {
      stop("Invalid transformed values encountered.", call. = FALSE)
    }
    IDD.series <- (1 / par.temporal[, 3]) * log(z)
  }

  #----------------------------------------------------------
  # Pre-generate bootstrap indices and back-transformation constants
  #----------------------------------------------------------
  boot_indices <- matrix(
    sample.int(max_time, size = max_time * n.boots, replace = TRUE),
    nrow = max_time,
    ncol = n.boots
  )

  mu_vec <- par.temporal[, 1]
  sigma_vec <- par.temporal[, 2]
  xi <- site_par[5]

  site_par.overall.boot <- matrix(NA_real_, nrow = n.boots, ncol = 5)

  #----------------------------------------------------------
  # Progress bar — controlled by use_progress_bar()
  #----------------------------------------------------------
  message("This calculation may take some time.")
  show_pb <- use_progress_bar(progress)
  if (show_pb) {
    pb <- utils::txtProgressBar(min = 0, max = n.boots, style = 3)
  }

  #----------------------------------------------------------
  # Bootstrap loop
  #----------------------------------------------------------
  for (r in seq_len(n.boots)) {
    resampled_IDD <- IDD.series[boot_indices[, r]]

    if (use_gumbel) {
      back.orig <- mu_vec + sigma_vec * resampled_IDD
    } else {
      back.orig <- mu_vec + (sigma_vec / xi) * (exp(resampled_IDD * xi) - 1)
    }

    parameters <- Fit_model(temperatures = back.orig, model = model)
    site_par.overall.boot[r, ] <- as.numeric(parameters[1, 1:5, drop = FALSE])

    if (show_pb) utils::setTxtProgressBar(pb, r)
  }

  if (show_pb) {
    close(pb)
  }

  #----------------------------------------------------------
  # Confidence intervals
  #----------------------------------------------------------
  CI_lower <- apply(
    site_par.overall.boot,
    2,
    quantile,
    probs = 0.025,
    na.rm = TRUE
  )
  CI_upper <- apply(
    site_par.overall.boot,
    2,
    quantile,
    probs = 0.975,
    na.rm = TRUE
  )

  CI_matrix <- rbind(CI_lower, CI_upper)
  rownames(CI_matrix) <- c("Lower 95% CI", "Upper 95% CI")
  colnames(CI_matrix) <- c("mu0", "mu1", "sigma0", "sigma1", "shape")
  CI_matrix
}
