.ci_profiled <- function(model, ci) {
  glm_ci <- tryCatch(
    {
      out <- as.data.frame(stats::confint(model, level = ci), stringsAsFactors = FALSE)
      names(out) <- c("CI_low", "CI_high")

      out$CI <- ci
      out$Parameter <- insight::get_parameters(model,
        effects = "fixed",
        component = "conditional",
        verbose = FALSE
      )$Parameter

      out <- out[c("Parameter", "CI", "CI_low", "CI_high")]
      rownames(out) <- NULL

      out
    },
    error = function(e) {
      NULL
    }
  )

  if (is.null(glm_ci)) {
    glm_ci <- .ci_generic(model, ci = ci)
  }

  glm_ci
}



# we need this function for models where confint and get_parameters return
# different length (e.g. as for "polr" models)
.ci_profiled2 <- function(model, ci) {
  glm_ci <- tryCatch(
    {
      out <- as.data.frame(stats::confint(model, level = ci), stringsAsFactors = FALSE)
      names(out) <- c("CI_low", "CI_high")

      out$CI <- ci
      out$Parameter <- .remove_backticks_from_string(rownames(out))

      out <- out[c("Parameter", "CI", "CI_low", "CI_high")]
      rownames(out) <- NULL

      out
    },
    error = function(e) {
      NULL
    }
  )

  if (is.null(glm_ci)) {
    glm_ci <- .ci_generic(model, ci = ci)
  }

  glm_ci
}


#' @keywords internal
.ci_profile_merMod <- function(x, ci, profiled, ...) {
  out <- as.data.frame(suppressWarnings(stats::confint(profiled, level = ci, ...)))
  rownames(out) <- gsub("`", "", rownames(out), fixed = TRUE)
  out <- out[rownames(out) %in% insight::find_parameters(x, effects = "fixed")$conditional, ]
  names(out) <- c("CI_low", "CI_high")

  # Clean up
  out$Parameter <- row.names(out)
  out$CI <- ci
  out <- out[c("Parameter", "CI", "CI_low", "CI_high")]
  row.names(out) <- NULL
  out
}


#' @keywords internal
.ci_profile_glmmTMB <- function(x, ci, profiled, component, ...) {
  if (is.null(profiled)) {
    out <- as.data.frame(stats::confint(x, method = "profile", level = ci, ...))
  } else {
    out <- tryCatch(as.data.frame(stats::confint(profiled, level = ci, ...)),
      error = function(e) NULL
    )
    if (is.null(out)) {
      out <- as.data.frame(stats::confint(x, method = "profile", level = ci, ...))
    }
  }
  .process_glmmTMB_CI(x, out, ci, component)
}



#' @keywords internal
.ci_uniroot_glmmTMB <- function(x, ci, component, ...) {
  out <- as.data.frame(stats::confint(x, level = ci, method = "uniroot", ...))
  .process_glmmTMB_CI(x, out, ci, component)
}



.process_glmmTMB_CI <- function(x, out, ci, component) {
  rownames(out) <- gsub("`", "", rownames(out), fixed = TRUE)

  pars <- insight::get_parameters(x,
    effects = "fixed",
    component = component,
    verbose = FALSE
  )

  param_names <- switch(component,
    "conditional" = pars$Parameter,
    "zi" = ,
    "zero_inflated" = paste0("zi~", pars$Parameter),
    c(
      pars$Parameter[pars$Component == "conditional"],
      paste0("zi~", pars$Parameter[pars$Component == "zero_inflated"])
    )
  )

  out <- out[rownames(out) %in% param_names, ]
  names(out) <- c("CI_low", "CI_high")

  # Clean up
  out$Parameter <- pars$Parameter
  out$CI <- ci
  out <- out[c("Parameter", "CI", "CI_low", "CI_high")]
  out$Component <- pars$Component
  row.names(out) <- NULL
  out
}



#' @keywords internal
.ci_boot_merMod <- function(x, ci, iterations = 500, effects = "fixed", ...) {
  insight::check_if_installed("lme4")

  # Compute
  out <- suppressWarnings(suppressMessages(as.data.frame(
    lme4::confint.merMod(x, level = ci, method = "boot", nsim = iterations, ...)
  )))
  rownames(out) <- gsub("`", "", rownames(out), fixed = TRUE)
  out <- out[rownames(out) %in% insight::find_parameters(x, effects = "fixed")$conditional, ]
  names(out) <- c("CI_low", "CI_high")

  # Clean up
  out$Parameter <- row.names(out)
  out$CI <- ci
  out <- out[c("Parameter", "CI", "CI_low", "CI_high")]
  row.names(out) <- NULL
  out
}
