# PK building blocks. See docs/model-spec.md Section 3 for parameter sources.
#
# IV doses are modeled as instantaneous bolus events (via deSolve's `events`
# argument), not as a finite-rate infusion forcing-function -- see the note
# in R/simulate.R for why (a real ~60-90 min infusion modeled as a narrow
# high-rate pulse was found to be numerically unreliable with an adaptive
# ODE solver). Bolus timing is close enough given every other timescale in
# this model is days to weeks.

#' Oral once/twice-daily dosing schedule -> discrete bolus event times to the
#' gut compartment (used by deSolve's `events` argument).
build_oral_events <- function(dose_mg, n_doses, interval_days, state_name = "Agut") {
  data.frame(
    var    = state_name,
    time   = (seq_len(n_doses) - 1) * interval_days,
    value  = dose_mg,
    method = "add"
  )
}

#' 2-compartment linear distribution + parallel Michaelis-Menten elimination.
#' Returns list(dAc, dAp) amount derivatives (mg/day). Concentration C is
#' mg/L == ug/mL given Vc/Vp in L, consistent with Km in ug/mL. Dosing enters
#' via bolus events on Ac, not through this derivative.
pk_2cmt_mm_deriv <- function(Ac, Ap, CL, Q, Vc, Vp, Vmax, Km) {
  C <- Ac / Vc
  dAc <- -CL * C - Q * C + Q * (Ap / Vp) - (Vmax * C) / (Km + C)
  dAp <- Q * C - Q * (Ap / Vp)
  list(dAc = dAc, dAp = dAp, C = C)
}

#' 1-compartment oral absorption (stub, used for linsitinib-type small
#' molecules). No MM term -- linear clearance only.
pk_oral_1cmt_deriv <- function(Agut, Ac, ka, CL, Vc) {
  dAgut <- -ka * Agut
  dAc   <- ka * Agut - CL * (Ac / Vc)
  list(dAgut = dAgut, dAc = dAc, C = Ac / Vc)
}
