// adme.sy -- Absorption, Distribution, Metabolism, Elimination
// pharmacokinetics as native Scyla.
//
// The ADME pipeline: what happens to a drug from ingestion to excretion.
// Every equation from published pharmacokinetic literature.
//
// Sources:
//   Rowland M, Tozer TN. Clinical Pharmacokinetics, 5th ed, 2011.
//   Shargel L et al. Applied Biopharmaceutics, 7th ed, 2012.
//   Goodman and Gilman's Pharmacological Basis of Therapeutics, 14th ed.
//
// Marjorie McCubbins + Aether, April 2026
// Patent pending: 64/034,536

struct PKParameters {
    drug_name: String,
    bioavailability: Float,
    tmax_hours: Float,
    half_life_hours: Float,
    vd_liters: Float,
    clearance_ml_min: Float,
    protein_binding_pct: Float,
    renal_elimination_pct: Float,
    hepatic_elimination_pct: Float,
    citation: String,
}

fn pkp(dn: String, f: Float, tm: Float, hl: Float, vd: Float, cl: Float, pb: Float, re: Float, he: Float, ci: String) -> PKParameters {
    return PKParameters { drug_name: dn, bioavailability: f, tmax_hours: tm, half_life_hours: hl, vd_liters: vd, clearance_ml_min: cl, protein_binding_pct: pb, renal_elimination_pct: re, hepatic_elimination_pct: he, citation: ci }
}

// =========================================================
// ABSORPTION
// =========================================================

// Bioavailability: F = (AUC_oral / AUC_iv) * (Dose_iv / Dose_oral)
// F = 1.0 for IV, < 1.0 for oral (first-pass metabolism)
fn bioavailability(auc_oral: Float, auc_iv: Float, dose_iv: Float, dose_oral: Float) -> Float {
    return (auc_oral / auc_iv) * (dose_iv / dose_oral)
}

// Rate of absorption: dA/dt = ka * D * F * exp(-ka * t)
// ka = absorption rate constant, D = dose, F = bioavailability
fn absorption_rate(ka: Float, dose: Float, f: Float, t: Float) -> Float {
    return ka * dose * f * exp(0.0 - ka * t)
}

// Amount absorbed at time t: A(t) = D * F * (1 - exp(-ka * t))
fn amount_absorbed(dose: Float, f: Float, ka: Float, t: Float) -> Float {
    return dose * f * (1.0 - exp(0.0 - ka * t))
}

// Time to max concentration (one-compartment oral):
// Tmax = ln(ka/ke) / (ka - ke)
fn tmax(ka: Float, ke: Float) -> Float {
    return ln(ka / ke) / (ka - ke)
}

// =========================================================
// DISTRIBUTION
// =========================================================

// Volume of distribution: Vd = Dose / C0 (after IV bolus)
// Vd > total body water (42L) = tissue binding
// Vd < plasma volume (3L) = high protein binding
fn volume_of_distribution(dose: Float, c0: Float) -> Float {
    return dose / c0
}

// Free (unbound) drug concentration
// Only free drug is pharmacologically active
fn free_concentration(total_conc: Float, protein_binding_fraction: Float) -> Float {
    return total_conc * (1.0 - protein_binding_fraction)
}

// Apparent Vd with protein binding
fn vd_apparent(vd_unbound: Float, fu_plasma: Float, fu_tissue: Float) -> Float {
    return vd_unbound * fu_plasma / fu_tissue
}

// Plasma protein binding displacement:
// New free fraction when displacing drug added
fn displaced_free_fraction(original_fu: Float, displacement_factor: Float) -> Float {
    let new_fu = original_fu * (1.0 + displacement_factor)
    if new_fu > 1.0 { return 1.0 }
    return new_fu
}

// Blood-brain barrier permeability estimate
// Lipophilic drugs (logP 1-3), MW < 400, minimal P-gp substrate
fn bbb_likely(log_p: Float, molecular_weight: Float) -> Bool {
    if log_p < 1.0 { return false }
    if log_p > 3.0 { return false }
    if molecular_weight > 400.0 { return false }
    return true
}

// =========================================================
// METABOLISM
// =========================================================

// First-pass extraction ratio: E = 1 - F (for well-absorbed drugs)
fn extraction_ratio(bioavailability_f: Float) -> Float {
    return 1.0 - bioavailability_f
}

// Hepatic clearance: CLh = Q * E
// Q = hepatic blood flow (~1500 mL/min in adults)
fn hepatic_clearance(hepatic_blood_flow: Float, extraction: Float) -> Float {
    return hepatic_blood_flow * extraction
}

// Hepatic blood flow (normal adult, mL/min)
fn normal_hepatic_blood_flow() -> Float {
    return 1500.0
}

// Intrinsic clearance from extraction ratio:
// CLint = Q * E / (1 - E) (well-stirred model)
fn intrinsic_clearance(hepatic_flow: Float, extraction: Float) -> Float {
    if extraction >= 1.0 { return 99999.0 }
    return hepatic_flow * extraction / (1.0 - extraction)
}

// Phase I metabolism: oxidation, reduction, hydrolysis (CYP450)
// Phase II metabolism: conjugation (glucuronidation, sulfation, acetylation, methylation, glutathione)
fn phase1_description() -> String {
    return "Phase I (functionalization): CYP450-mediated oxidation, reduction, hydrolysis. Introduces or exposes functional group (-OH, -NH2, -SH). Often produces active/toxic metabolites. Affected by CYP inhibitors/inducers."
}

fn phase2_description() -> String {
    return "Phase II (conjugation): Glucuronidation (UGT), sulfation (SULT), acetylation (NAT), methylation (COMT/TPMT), glutathione conjugation (GST). Produces polar, water-soluble, inactive metabolites for renal excretion. Exception: morphine-6-glucuronide is active."
}

// =========================================================
// ELIMINATION
// =========================================================

// Elimination rate constant from half-life: ke = ln(2) / t_half
fn elimination_rate_constant(t_half: Float) -> Float {
    return 0.6931471805599453 / t_half
}

// Half-life from clearance and Vd: t_half = 0.693 * Vd / CL
fn half_life_from_cl_vd(clearance: Float, vd: Float) -> Float {
    return 0.6931471805599453 * vd / clearance
}

// Total clearance: CL = ke * Vd
fn total_clearance(ke: Float, vd: Float) -> Float {
    return ke * vd
}

// Renal clearance: CLr = fe * CL (fe = fraction excreted unchanged)
fn renal_clearance(total_cl: Float, fraction_renal: Float) -> Float {
    return total_cl * fraction_renal
}

// Non-renal clearance: CLnr = CL - CLr
fn nonrenal_clearance(total_cl: Float, renal_cl: Float) -> Float {
    return total_cl - renal_cl
}

// Concentration at time t (IV bolus, one-compartment):
// C(t) = C0 * exp(-ke * t) = (Dose/Vd) * exp(-ke * t)
fn concentration_iv(dose: Float, vd: Float, ke: Float, t: Float) -> Float {
    return (dose / vd) * exp(0.0 - ke * t)
}

// Concentration at time t (oral, one-compartment, Bateman):
// C(t) = (F*D*ka) / (Vd*(ka-ke)) * (exp(-ke*t) - exp(-ka*t))
fn concentration_oral(dose: Float, f: Float, vd: Float, ka: Float, ke: Float, t: Float) -> Float {
    return (f * dose * ka) / (vd * (ka - ke)) * (exp(0.0 - ke * t) - exp(0.0 - ka * t))
}

// AUC (single dose, IV bolus): AUC = Dose / CL
fn auc_iv(dose: Float, clearance: Float) -> Float {
    return dose / clearance
}

// AUC (single dose, oral): AUC = F * Dose / CL
fn auc_oral(dose: Float, f: Float, clearance: Float) -> Float {
    return f * dose / clearance
}

// =========================================================
// STEADY STATE (Multiple Dosing)
// =========================================================

// Accumulation factor: R = 1 / (1 - exp(-ke * tau))
// tau = dosing interval
fn accumulation_factor(ke: Float, tau: Float) -> Float {
    return 1.0 / (1.0 - exp(0.0 - ke * tau))
}

// Steady-state average concentration: Css_avg = F * Dose / (CL * tau)
fn css_average(dose: Float, f: Float, clearance: Float, tau: Float) -> Float {
    return f * dose / (clearance * tau)
}

// Steady-state max: Css_max = (F * Dose / Vd) * (1 / (1 - exp(-ke * tau)))
fn css_max(dose: Float, f: Float, vd: Float, ke: Float, tau: Float) -> Float {
    return (f * dose / vd) * accumulation_factor(ke, tau)
}

// Steady-state min (trough): Css_min = Css_max * exp(-ke * tau)
fn css_min(css_max_val: Float, ke: Float, tau: Float) -> Float {
    return css_max_val * exp(0.0 - ke * tau)
}

// Time to steady state: ~4-5 half-lives
fn time_to_steady_state(t_half: Float) -> Float {
    return 4.5 * t_half
}

// Number of doses to reach steady state
fn doses_to_steady_state(t_half: Float, tau: Float) -> Float {
    return 4.5 * t_half / tau
}

// Loading dose: DL = Css_target * Vd / F
fn loading_dose(target_css: Float, vd: Float, f: Float) -> Float {
    return target_css * vd / f
}

// Maintenance dose: DM = Css_target * CL * tau / F
fn maintenance_dose(target_css: Float, clearance: Float, tau: Float, f: Float) -> Float {
    return target_css * clearance * tau / f
}

// =========================================================
// RENAL DOSE ADJUSTMENT
// =========================================================

// Cockcroft-Gault CrCl estimation (mL/min):
// CrCl = ((140 - age) * weight_kg) / (72 * serum_creatinine)
// Multiply by 0.85 for females
fn cockcroft_gault(age: Float, weight_kg: Float, serum_cr: Float, is_female: Bool) -> Float {
    let crcl = ((140.0 - age) * weight_kg) / (72.0 * serum_cr)
    if is_female { return crcl * 0.85 }
    return crcl
}

// Dose adjustment factor based on CrCl:
// Q = fraction of normal dose = CLadjusted / CLnormal
fn renal_dose_fraction(crcl_patient: Float, crcl_normal: Float, fraction_renal: Float) -> Float {
    return 1.0 - fraction_renal * (1.0 - crcl_patient / crcl_normal)
}

// CKD staging by GFR
fn ckd_stage_by_gfr(gfr: Float) -> String {
    if gfr >= 90.0 { return "Stage 1: Normal or high GFR (>= 90 mL/min/1.73m2). Monitor if proteinuria present." }
    if gfr >= 60.0 { return "Stage 2: Mildly decreased (60-89). Mild dose adjustments for some drugs." }
    if gfr >= 45.0 { return "Stage 3a: Mildly to moderately decreased (45-59). Adjust renally cleared drugs." }
    if gfr >= 30.0 { return "Stage 3b: Moderately to severely decreased (30-44). Significant dose reductions needed." }
    if gfr >= 15.0 { return "Stage 4: Severely decreased (15-29). Major dose reductions. Avoid nephrotoxic drugs." }
    return "Stage 5: Kidney failure (< 15). Dialysis consideration. Many drugs contraindicated."
}

// =========================================================
// HEPATIC DOSE ADJUSTMENT
// =========================================================

// Child-Pugh score interpretation
fn child_pugh_class(score: Int) -> String {
    if score <= 6 { return "Class A (5-6 points): Mild hepatic impairment. Most drugs safe at normal doses. Monitor LFTs." }
    if score <= 9 { return "Class B (7-9 points): Moderate impairment. Reduce doses of hepatically cleared drugs by 25-50%. Avoid hepatotoxic drugs." }
    return "Class C (10-15 points): Severe impairment. Reduce doses 50-75% or avoid. Many drugs contraindicated. Risk of hepatic encephalopathy."
}

// =========================================================
// TWO-COMPARTMENT MODEL
// =========================================================

// Two-compartment IV bolus:
// C(t) = A * exp(-alpha * t) + B * exp(-beta * t)
// alpha = distribution phase (fast), beta = elimination phase (slow)
fn two_compartment_iv(a_coeff: Float, alpha: Float, b_coeff: Float, beta: Float, t: Float) -> Float {
    return a_coeff * exp(0.0 - alpha * t) + b_coeff * exp(0.0 - beta * t)
}

// Distribution half-life: t_half_alpha = ln(2) / alpha
fn distribution_half_life(alpha: Float) -> Float {
    return 0.6931471805599453 / alpha
}

// Terminal elimination half-life: t_half_beta = ln(2) / beta
fn terminal_half_life(beta: Float) -> Float {
    return 0.6931471805599453 / beta
}

// Micro-rate constants from macro constants:
// k21 = (A*beta + B*alpha) / (A + B)
fn k21_from_macro(a_coeff: Float, alpha: Float, b_coeff: Float, beta: Float) -> Float {
    return (a_coeff * beta + b_coeff * alpha) / (a_coeff + b_coeff)
}

// k10 = alpha * beta / k21
fn k10_from_macro(alpha: Float, beta: Float, k21: Float) -> Float {
    return alpha * beta / k21
}

// k12 = alpha + beta - k21 - k10
fn k12_from_macro(alpha: Float, beta: Float, k21: Float, k10: Float) -> Float {
    return alpha + beta - k21 - k10
}

// =========================================================
// THERAPEUTIC DRUG MONITORING
// =========================================================

fn tdm_drug_requires_monitoring(drug_name: String) -> Bool {
    if drug_name == "VANCOMYCIN" { return true }
    if drug_name == "GENTAMICIN" { return true }
    if drug_name == "TOBRAMYCIN" { return true }
    if drug_name == "AMIKACIN" { return true }
    if drug_name == "PHENYTOIN" { return true }
    if drug_name == "CARBAMAZEPINE" { return true }
    if drug_name == "VALPROIC ACID" { return true }
    if drug_name == "LITHIUM" { return true }
    if drug_name == "DIGOXIN" { return true }
    if drug_name == "THEOPHYLLINE" { return true }
    if drug_name == "CYCLOSPORINE" { return true }
    if drug_name == "TACROLIMUS" { return true }
    if drug_name == "SIROLIMUS" { return true }
    if drug_name == "METHOTREXATE" { return true }
    if drug_name == "WARFARIN" { return true }
    return false
}

fn tdm_therapeutic_range(drug_name: String) -> String {
    if drug_name == "VANCOMYCIN" { return "Trough 15-20 mcg/mL (serious infections); AUC/MIC 400-600 (preferred method). Nephrotoxicity > 20 mcg/mL. Rowland 5th ed." }
    if drug_name == "GENTAMICIN" { return "Traditional: peak 5-10, trough < 2 mcg/mL. Extended-interval: Cmax 15-25, undetectable at 24h. Ototoxicity and nephrotoxicity if trough > 2." }
    if drug_name == "PHENYTOIN" { return "Total 10-20 mcg/mL; free 1-2 mcg/mL. Adjust for albumin: corrected = measured / (0.2 * albumin + 0.1). Nonlinear kinetics (Michaelis-Menten)." }
    if drug_name == "LITHIUM" { return "Acute mania: 0.8-1.2 mEq/L. Maintenance: 0.6-0.8 mEq/L. Toxicity > 1.5 mEq/L. Narrow therapeutic index. Monitor q3-6 months." }
    if drug_name == "DIGOXIN" { return "HF: 0.5-0.9 ng/mL (DIG trial mortality data). Atrial fib: 0.8-2.0 ng/mL. Toxicity > 2.0. Draw 6+ hours post-dose. Hypokalemia potentiates toxicity." }
    if drug_name == "WARFARIN" { return "INR 2.0-3.0 (most indications). INR 2.5-3.5 (mechanical heart valve). Vitamin K antidote. Monitor weekly then monthly." }
    if drug_name == "TACROLIMUS" { return "Kidney transplant: 5-15 ng/mL (first 3 months), 5-10 (maintenance). Liver transplant: 10-15 (early), 5-10 (maintenance). CYP3A4 substrate." }
    if drug_name == "CYCLOSPORINE" { return "Trough 150-300 ng/mL (renal transplant, early). 100-200 (maintenance). C2 monitoring (2h post-dose) may be superior. CYP3A4 substrate." }
    if drug_name == "VALPROIC ACID" { return "Epilepsy: 50-100 mcg/mL. Free level 6-22 mcg/mL. Hepatotoxicity, pancreatitis, teratogenicity (neural tube defects). Highly protein bound." }
    if drug_name == "THEOPHYLLINE" { return "Asthma: 5-15 mcg/mL. Toxicity > 20 (nausea, arrhythmias, seizures). CYP1A2 substrate. Smoking induces clearance." }
    if drug_name == "METHOTREXATE" { return "High-dose (>500 mg/m2): 24h level < 10 uM, 48h < 1 uM, 72h < 0.1 uM. Leucovorin rescue required. Monitor renal function, CBC." }
    return ""
}

// =========================================================
// COUNTS
// =========================================================

fn adme_function_count() -> Int {
    return 45
}
