// toxicology.sy -- Drug toxicology, dose-response, organ toxicity markers,
// antidotes, and clinical toxicology as native Scyla.
//
// Sources:
//   Klaassen CD. Casarett and Doull's Toxicology, 9th ed, McGraw-Hill, 2019.
//   Nelson LS et al. Goldfrank's Toxicologic Emergencies, 11th ed, 2019.
//
// Marjorie McCubbins + Aether, April 2026
// Patent pending: 64/034,536


// ==========================================================
// STRUCTS
// ==========================================================

struct OrganMarker {
    organ: String,
    biomarker: String,
    normal_low: Float,
    normal_high: Float,
    unit: String,
    toxic_threshold: Float,
    mechanism: String,
    common_drugs: String,
    citation: String,
}

struct Toxidrome {
    name: String,
    vital_signs: String,
    pupils: String,
    skin: String,
    mental_status: String,
    other_findings: String,
    treatment: String,
    prototype_drugs: String,
    citation: String,
}

struct AntidoteEntry {
    poison: String,
    antidote: String,
    mechanism_of_antidote: String,
    dosing: String,
    time_window: String,
    monitoring: String,
    citation: String,
}

struct NACProtocol {
    weight_kg: Float,
    bag_one_dose_mg: Float,
    bag_one_volume_ml: Float,
    bag_one_duration_min: Float,
    bag_two_dose_mg: Float,
    bag_two_volume_ml: Float,
    bag_two_duration_min: Float,
    bag_three_dose_mg: Float,
    bag_three_volume_ml: Float,
    bag_three_duration_min: Float,
    total_dose_mg: Float,
    total_duration_hours: Float,
    citation: String,
}

struct QTDrug {
    name: String,
    risk_category: String,
    typical_qtc_prolongation_ms: Float,
    mechanism: String,
    citation: String,
}


// ==========================================================
// SECTION ONE: DOSE-RESPONSE RELATIONSHIPS
// ==========================================================
//
// The dose-response curve is the foundation of toxicology.
// Paracelsus (1493-1541): "The dose makes the poison."
// All dose-response relationships follow sigmoidal (Hill) kinetics
// at the population level.
//
// Casarett and Doull's, 9th ed, Ch 2: Principles of Toxicology.

// Hill equation (sigmoidal dose-response):
// Effect = Emax * D^n / (EC50^n + D^n)
// Emax = maximal effect, EC50 = dose producing 50% effect,
// n = Hill coefficient (steepness)
fn dose_response_sigmoid(dose: Float, emax: Float, ec50: Float, hill_n: Float) -> Float {
    let d_n = pow(dose, hill_n)
    let ec_n = pow(ec50, hill_n)
    return emax * d_n / (ec_n + d_n)
}

// Therapeutic index: TI = LD50 / ED50
// Higher TI = safer drug. TI < 2 = narrow therapeutic index (warfarin, digoxin, lithium)
// Casarett and Doull's 9th ed, Ch 2, p 48.
fn therapeutic_index(ld50: Float, ed50: Float) -> Float {
    return ld50 / ed50
}

// Margin of safety: MOS = LD01 / ED99
// More conservative than TI. MOS < 1 means the dose that works for 99%
// of people is already lethal for 1%.
// Casarett and Doull's 9th ed, Ch 2, p 49.
fn margin_of_safety(ld01: Float, ed99: Float) -> Float {
    return ld01 / ed99
}

// Allometric scaling: interspecies dose conversion
// Human Equivalent Dose = NOAEL * (animal_weight / human_weight)^0.25
// Based on body surface area scaling (FDA Guidance for Industry, 2005).
// Casarett and Doull's 9th ed, Ch 2, pp 50-52.
fn noael_to_human_dose(noael_mg_kg: Float, animal_weight_kg: Float, human_weight_kg: Float) -> Float {
    let ratio = animal_weight_kg / human_weight_kg
    let scaling_factor = pow(ratio, 0.25)
    return noael_mg_kg * scaling_factor
}

// Log-linear (probit) dose-response:
// Response = slope * log_dose + intercept
// Used in probit analysis for LD50 determination.
// Casarett and Doull's 9th ed, Ch 2, pp 44-46.
fn dose_response_log_linear(log_dose: Float, slope: Float, intercept: Float) -> Float {
    return slope * log_dose + intercept
}

// Certain safety factor: CSF = ED99 / LD01
// Inverse of MOS. CSF > 1 means overlap between effective and lethal doses.
fn certain_safety_factor(ed99: Float, ld01: Float) -> Float {
    return ed99 / ld01
}


// ==========================================================
// SECTION TWO: ORGAN TOXICITY MARKERS
// ==========================================================
//
// Organ-specific biomarkers allow detection of subclinical toxicity
// before organ failure occurs. Each marker reflects a specific
// cellular injury mechanism.
//
// Casarett and Doull's 9th ed, Ch 13-17 (organ-specific toxicology).
// Goldfrank's 11th ed, Part C (specific organ toxicity).

fn om(org: String, bio: String, nl: Float, nh: Float, u: String, tt: Float, mech: String, drugs: String, cite: String) -> OrganMarker {
    return OrganMarker { organ: org, biomarker: bio, normal_low: nl, normal_high: nh, unit: u, toxic_threshold: tt, mechanism: mech, common_drugs: drugs, citation: cite }
}

// -----------------------------------------------------------
// HEPATOTOXICITY MARKERS
// -----------------------------------------------------------
// The liver is the primary site of drug metabolism and therefore
// the most common target of drug-induced toxicity. ALT is the
// most liver-specific aminotransferase; AST is less specific
// (also in heart, muscle, kidney).
//
// Casarett and Doull's 9th ed, Ch 13: Toxic Responses of the Liver.
// Goldfrank's 11th ed, Ch 26: Hepatic Principles.

fn hepatotoxicity(marker: String) -> OrganMarker {
    if marker == "ALT" { return om("liver", "Alanine aminotransferase (ALT/SGPT)", 7.0, 56.0, "U/L", 168.0, "Cytoplasmic enzyme released on hepatocyte membrane damage. Most liver-specific transaminase. ALT > 3x ULN = significant hepatocellular injury.", "acetaminophen, isoniazid, statins, valproic acid, methotrexate, amiodarone, NSAIDs", "Casarett 9th ed Ch 13; Goldfrank 11th ed Ch 26") }
    if marker == "AST" { return om("liver", "Aspartate aminotransferase (AST/SGOT)", 10.0, 40.0, "U/L", 120.0, "Mitochondrial and cytoplasmic enzyme. Less liver-specific than ALT (also in cardiac/skeletal muscle). AST:ALT ratio > 2 suggests alcoholic liver disease.", "acetaminophen, isoniazid, phenytoin, alcohol, statins", "Casarett 9th ed Ch 13; Goldfrank 11th ed Ch 26") }
    if marker == "ALP" { return om("liver", "Alkaline phosphatase (ALP)", 44.0, 147.0, "U/L", 441.0, "Canalicular enzyme. Elevated in cholestatic (obstructive) injury. Also from bone. GGT co-elevation confirms hepatic origin.", "amoxicillin-clavulanate, erythromycin, chlorpromazine, anabolic steroids, oral contraceptives", "Casarett 9th ed Ch 13") }
    if marker == "GGT" { return om("liver", "Gamma-glutamyl transferase (GGT)", 0.0, 45.0, "U/L", 135.0, "Microsomal enzyme induced by alcohol and enzyme-inducing drugs. Confirms hepatic origin of elevated ALP. Sensitive but nonspecific.", "alcohol, phenytoin, carbamazepine, barbiturates, rifampin", "Casarett 9th ed Ch 13") }
    if marker == "BILIRUBIN" { return om("liver", "Total bilirubin", 0.1, 1.2, "mg/dL", 2.4, "End product of heme catabolism. Conjugated by UGT1A1 in liver. Elevated direct bilirubin = cholestasis. Elevated indirect = hemolysis or Gilbert syndrome.", "rifampin, atazanavir, acetaminophen (in ALF), isoniazid", "Casarett 9th ed Ch 13") }
    if marker == "INR" { return om("liver", "International Normalized Ratio (INR)", 0.8, 1.1, "ratio", 1.5, "Reflects synthetic function (factors II, VII, IX, X). INR > 1.5 without anticoagulants = significant hepatic synthetic failure. First to rise in acute liver failure.", "acetaminophen overdose (acute liver failure), warfarin, severe hepatotoxins", "Goldfrank 11th ed Ch 26") }
    return om("liver", "Unknown marker", 0.0, 0.0, "", 0.0, "Marker not recognized", "", "")
}

// Hy's Law: ALT > 3x ULN + bilirubin > 2x ULN (without ALP > 2x ULN)
// = 10% risk of fatal drug-induced liver injury (DILI)
// Named after Hyman Zimmerman. FDA uses as stopping rule in clinical trials.
// Casarett 9th ed, Ch 13, p 563.
fn hys_law(alt: Float, alt_uln: Float, bilirubin: Float, bili_uln: Float, alp: Float, alp_uln: Float) -> String {
    let alt_ratio = alt / alt_uln
    let bili_ratio = bilirubin / bili_uln
    let alp_ratio = alp / alp_uln
    if alt_ratio > 3.0 {
        if bili_ratio > 2.0 {
            if alp_ratio < 2.0 {
                return "HY'S LAW POSITIVE: ALT > 3x ULN + bilirubin > 2x ULN without cholestasis. 10% mortality risk for drug-induced liver injury. STOP THE DRUG IMMEDIATELY. FDA stopping rule for clinical trials. (Zimmerman HJ, Hepatotoxicity, 1999)"
            }
            return "Mixed pattern: ALT and bilirubin elevated but ALP also elevated. Consider cholestatic or mixed injury. Monitor closely."
        }
        return "ALT > 3x ULN but bilirubin normal. Hepatocellular injury without jaundice. Monitor for progression. Consider dose reduction."
    }
    if bili_ratio > 2.0 {
        return "Bilirubin elevated without significant ALT elevation. Consider cholestatic injury, hemolysis, or Gilbert syndrome."
    }
    return "No Hy's Law criteria met. ALT and bilirubin within acceptable range."
}

// -----------------------------------------------------------
// NEPHROTOXICITY MARKERS
// -----------------------------------------------------------
// The kidney concentrates and excretes drugs and metabolites,
// making it vulnerable to toxicity. Traditional markers (BUN,
// creatinine) are late. Novel markers (KIM-1, NGAL) detect
// injury days earlier.
//
// Casarett and Doull's 9th ed, Ch 14: Toxic Responses of the Kidney.
// Goldfrank's 11th ed, Ch 27: Renal Principles.

fn nephrotoxicity(marker: String) -> OrganMarker {
    if marker == "BUN" { return om("kidney", "Blood urea nitrogen (BUN)", 7.0, 20.0, "mg/dL", 40.0, "Urea is the end product of protein catabolism. BUN rises in prerenal (dehydration, CHF), intrinsic renal, and postrenal (obstruction) azotemia. BUN:Cr ratio > 20 suggests prerenal.", "aminoglycosides, amphotericin B, cisplatin, NSAIDs, ACE inhibitors, contrast dye", "Casarett 9th ed Ch 14") }
    if marker == "CREATININE" { return om("kidney", "Serum creatinine", 0.7, 1.3, "mg/dL", 2.0, "Creatinine is a product of muscle creatine phosphate metabolism. Filtered at glomerulus, not reabsorbed. Rises only after 50% GFR loss (insensitive early marker).", "aminoglycosides, vancomycin, cisplatin, methotrexate, lithium, tenofovir, NSAIDs", "Casarett 9th ed Ch 14") }
    if marker == "GFR" { return om("kidney", "Glomerular filtration rate (eGFR)", 90.0, 120.0, "mL/min/1.73m2", 60.0, "Estimated from CKD-EPI equation (2021 race-free). GFR < 60 = CKD Stage 3+. Gold standard: inulin clearance. GFR < 15 = kidney failure.", "aminoglycosides, cisplatin, cyclosporine, tacrolimus, lithium", "Casarett 9th ed Ch 14") }
    if marker == "CYSTATIN_C" { return om("kidney", "Cystatin C", 0.5, 1.0, "mg/L", 1.5, "Small protein produced by all nucleated cells at constant rate. Not affected by muscle mass (unlike creatinine). More accurate GFR estimate in elderly, children, and extremes of body composition.", "aminoglycosides, cisplatin, contrast media", "Casarett 9th ed Ch 14") }
    if marker == "KIM1" { return om("kidney", "Kidney injury molecule-1 (KIM-1)", 0.0, 0.5, "ng/mL", 1.0, "Type I transmembrane glycoprotein. Undetectable in normal kidney. Markedly upregulated in proximal tubular injury. FDA-qualified preclinical biomarker.", "cisplatin, gentamicin, vancomycin, contrast media", "Casarett 9th ed Ch 14; Bonventre JV, J Clin Invest 2009") }
    if marker == "NGAL" { return om("kidney", "Neutrophil gelatinase-associated lipocalin (NGAL)", 0.0, 150.0, "ng/mL", 300.0, "Iron-transporting protein induced in distal tubule within 2 hours of injury. Rises 24-48 hours before creatinine. Predicts AKI in ICU and post-cardiac surgery.", "cisplatin, aminoglycosides, contrast media, amphotericin B", "Casarett 9th ed Ch 14; Mishra J, Lancet 2005") }
    return om("kidney", "Unknown marker", 0.0, 0.0, "", 0.0, "Marker not recognized", "", "")
}

// -----------------------------------------------------------
// CARDIOTOXICITY MARKERS
// -----------------------------------------------------------
// Cardiac biomarkers detect myocyte necrosis (troponin),
// myocardial wall stress (BNP/NT-proBNP), and conduction
// abnormalities (QTc interval).
//
// Casarett and Doull's 9th ed, Ch 15: Toxic Responses of the Heart.
// Goldfrank's 11th ed, Ch 16: Cardiovascular Principles.

fn cardiotoxicity(marker: String) -> OrganMarker {
    if marker == "TROPONIN_I" { return om("heart", "Troponin I (cTnI)", 0.0, 0.04, "ng/mL", 0.4, "Cardiac-specific contractile protein. Released 3-6 hours after myocyte necrosis. High-sensitivity assays detect sub-clinical injury from cardiotoxic drugs. Rises with doxorubicin, 5-FU, trastuzumab.", "doxorubicin, 5-fluorouracil, trastuzumab, cocaine, carbon monoxide", "Casarett 9th ed Ch 15; Goldfrank 11th ed Ch 16") }
    if marker == "TROPONIN_T" { return om("heart", "Troponin T (cTnT)", 0.0, 0.01, "ng/mL", 0.1, "Cardiac-specific contractile protein. Less specific than cTnI (can be elevated in renal failure, skeletal myopathy). hs-cTnT used for serial monitoring of anthracycline cardiotoxicity.", "doxorubicin, cyclophosphamide, 5-fluorouracil, cocaine", "Casarett 9th ed Ch 15") }
    if marker == "BNP" { return om("heart", "B-type natriuretic peptide (BNP)", 0.0, 100.0, "pg/mL", 400.0, "Secreted by ventricular myocytes in response to wall stretch. BNP > 400 pg/mL = likely heart failure. Used to monitor cardiotoxicity during chemotherapy.", "doxorubicin, trastuzumab, imatinib, cyclophosphamide", "Casarett 9th ed Ch 15") }
    if marker == "NT_PROBNP" { return om("heart", "N-terminal pro-BNP (NT-proBNP)", 0.0, 125.0, "pg/mL", 450.0, "Inactive fragment co-released with BNP. Longer half-life than BNP. Age-dependent cutoffs. Renally cleared (adjust for CKD). Detects subclinical cardiotoxicity.", "doxorubicin, trastuzumab, bevacizumab", "Casarett 9th ed Ch 15") }
    if marker == "QTC" { return om("heart", "QTc interval", 350.0, 440.0, "ms", 500.0, "Heart-rate-corrected QT interval. QTc > 500 ms = high risk of Torsades de Pointes (polymorphic VT). > 60 ms increase from baseline is also concerning.", "amiodarone, sotalol, haloperidol, methadone, ondansetron, fluoroquinolones, macrolides", "Casarett 9th ed Ch 15; Goldfrank 11th ed Ch 16") }
    return om("heart", "Unknown marker", 0.0, 0.0, "", 0.0, "Marker not recognized", "", "")
}

// -----------------------------------------------------------
// NEUROTOXICITY MARKERS
// -----------------------------------------------------------
// Neurotoxicity assessment relies heavily on clinical findings
// rather than blood biomarkers. The CNS is protected by the BBB,
// making serum markers less informative than for other organs.
//
// Casarett and Doull's 9th ed, Ch 16: Toxic Responses of the Nervous System.
// Goldfrank's 11th ed, Ch 19: Neurologic Principles.

fn neurotoxicity(marker: String) -> OrganMarker {
    if marker == "MENTAL_STATUS" { return om("CNS", "Mental status / Glasgow Coma Scale", 15.0, 15.0, "GCS points", 8.0, "GCS < 8 = coma, requires airway protection. Altered mental status is the most common manifestation of neurotoxicity. Ranges from agitation (sympathomimetics) to obtundation (opioids, sedatives).", "opioids, benzodiazepines, barbiturates, ethanol, anticholinergics, lithium, lead", "Goldfrank 11th ed Ch 19") }
    if marker == "SEIZURE_THRESHOLD" { return om("CNS", "Seizure threshold (clinical assessment)", 0.0, 0.0, "clinical", 1.0, "Many drugs lower seizure threshold by blocking GABA-A receptors, inhibiting glutamate reuptake, or causing metabolic derangements. Value of 1 indicates seizures present.", "isoniazid, tramadol, bupropion, theophylline, organophosphates, TCA, lithium, cocaine", "Goldfrank 11th ed Ch 19; Casarett 9th ed Ch 16") }
    if marker == "NSE" { return om("CNS", "Neuron-specific enolase (NSE)", 0.0, 16.3, "ng/mL", 33.0, "Glycolytic enzyme in neurons. Released after neuronal death. Elevated after cardiac arrest, TBI, organophosphate poisoning. Research biomarker for neurotoxicity severity.", "carbon monoxide, organophosphates, methanol", "Casarett 9th ed Ch 16") }
    if marker == "S100B" { return om("CNS", "S100B protein", 0.0, 0.1, "ug/L", 0.5, "Calcium-binding protein in astrocytes. Released after BBB disruption or glial injury. Elevated in CO poisoning, lead encephalopathy, severe neurotoxin exposure.", "carbon monoxide, lead, methanol, ethylene glycol", "Casarett 9th ed Ch 16") }
    return om("CNS", "Unknown marker", 0.0, 0.0, "", 0.0, "Marker not recognized", "", "")
}

// -----------------------------------------------------------
// HEMATOTOXICITY MARKERS
// -----------------------------------------------------------
// Drug-induced hematotoxicity includes myelosuppression
// (pancytopenia), isolated cytopenias, and hemolysis.
// Chemotherapy agents are the most common cause.
//
// Casarett and Doull's 9th ed, Ch 11: Toxic Responses of the Blood.
// Goldfrank's 11th ed, Ch 22: Hematologic Principles.

fn hematotoxicity(marker: String) -> OrganMarker {
    if marker == "WBC" { return om("bone_marrow", "White blood cell count (WBC)", 4.5, 11.0, "x10^3/uL", 1.0, "Leukopenia < 4.5; leukocytosis > 11. Drug-induced leukopenia typically from myelosuppression. Nadir 7-14 days post chemotherapy.", "methotrexate, cyclophosphamide, clozapine, carbamazepine, ganciclovir, dapsone", "Casarett 9th ed Ch 11") }
    if marker == "ANC" { return om("bone_marrow", "Absolute neutrophil count (ANC)", 1.5, 8.0, "x10^3/uL", 0.5, "ANC < 1500 = neutropenia. ANC < 500 = severe neutropenia (high infection risk). ANC < 100 = agranulocytosis. Febrile neutropenia is an oncologic emergency.", "chemotherapy (all classes), clozapine, methimazole, ticlopidine, sulfasalazine", "Casarett 9th ed Ch 11; Goldfrank 11th ed Ch 22") }
    if marker == "PLATELETS" { return om("bone_marrow", "Platelet count", 150.0, 400.0, "x10^3/uL", 50.0, "Thrombocytopenia < 150. < 50 = bleeding risk with procedures. < 20 = spontaneous bleeding risk. < 10 = life-threatening. Drug-induced: immune-mediated (heparin-HIT) or myelosuppressive.", "heparin (HIT), chemotherapy, valproic acid, linezolid, quinine, GPIIb/IIIa inhibitors", "Casarett 9th ed Ch 11") }
    if marker == "HEMOGLOBIN" { return om("bone_marrow", "Hemoglobin", 12.0, 17.5, "g/dL", 7.0, "Anemia from myelosuppression (aplastic), hemolysis (oxidative -- G6PD), or bleeding. Hgb < 7 = transfusion threshold in stable patients. Drug-induced hemolytic anemia: dapsone, nitrofurantoin, primaquine (G6PD).", "dapsone, primaquine, nitrofurantoin, ribavirin, methyldopa, chemotherapy", "Casarett 9th ed Ch 11; Goldfrank 11th ed Ch 22") }
    if marker == "RETICULOCYTES" { return om("bone_marrow", "Reticulocyte count", 0.5, 2.5, "percent", 0.0, "Immature RBCs. Low reticulocytes + anemia = marrow failure (aplastic anemia, myelosuppression). High reticulocytes + anemia = hemolysis or bleeding (appropriate marrow response).", "chloramphenicol, benzene, chemotherapy (all), methotrexate", "Casarett 9th ed Ch 11") }
    return om("bone_marrow", "Unknown marker", 0.0, 0.0, "", 0.0, "Marker not recognized", "", "")
}


// ==========================================================
// SECTION THREE: QT PROLONGATION
// ==========================================================
//
// QT interval represents ventricular depolarization and repolarization.
// Prolonged QT increases risk of Torsades de Pointes (TdP),
// a polymorphic ventricular tachycardia that can degenerate to
// ventricular fibrillation and sudden cardiac death.
//
// Mechanism: Most QT-prolonging drugs block hERG (IKr) potassium
// channels, delaying repolarization.
//
// Goldfrank's 11th ed, Ch 16: Cardiovascular Principles.
// Casarett and Doull's 9th ed, Ch 15: Toxic Responses of the Heart.

// Bazett correction: QTc = QT / sqrt(RR)
// RR interval in seconds. Most commonly used. Overcorrects at high HR.
// Bazett HC. Heart 7:353-370, 1920.
fn qtc_bazett(qt_ms: Float, rr_ms: Float) -> Float {
    let rr_sec = rr_ms / 1000.0
    return qt_ms / sqrt(rr_sec)
}

// Fridericia correction: QTc = QT / cbrt(RR)
// cbrt(x) = x^(1/3). More accurate at extreme heart rates.
// Preferred by FDA for drug studies (ICH E14 guidance).
// Fridericia LS. Acta Med Scand 1920.
fn qtc_fridericia(qt_ms: Float, rr_ms: Float) -> Float {
    let rr_sec = rr_ms / 1000.0
    return qt_ms / pow(rr_sec, 0.3333333333333333)
}

// QT risk assessment based on QTc value
fn qt_risk_assessment(qtc: Float) -> String {
    if qtc < 350.0 { return "SHORT QT: QTc < 350 ms. Consider short QT syndrome (rare). Associated with atrial fibrillation and sudden cardiac death." }
    if qtc <= 440.0 { return "NORMAL: QTc 350-440 ms. No increased risk of Torsades de Pointes." }
    if qtc <= 470.0 { return "BORDERLINE: QTc 441-470 ms. Monitor for further prolongation. Review concomitant QT-prolonging drugs, electrolytes (K+, Mg2+, Ca2+). Avoid adding additional QT-prolonging agents." }
    if qtc <= 500.0 { return "PROLONGED: QTc 471-500 ms. Significant TdP risk. Discontinue offending drug if possible. Correct hypokalemia (target K+ > 4.0) and hypomagnesemia. Continuous telemetry." }
    return "DANGEROUS: QTc > 500 ms. HIGH risk of Torsades de Pointes and sudden cardiac death. STOP all QT-prolonging drugs. IV magnesium sulfate 2g. Correct electrolytes. Temporary pacing if symptomatic. ICU admission."
}

// Known high-risk QT-prolonging drugs
// CredibleMeds.org risk categories; Goldfrank's 11th ed Ch 16.
fn qt_drug(name: String) -> QTDrug {
    if name == "AMIODARONE" { return QTDrug { name: "Amiodarone", risk_category: "Known TdP risk", typical_qtc_prolongation_ms: 30.0, mechanism: "Blocks IKr (hERG), IKs, INa, and ICa-L. Class III antiarrhythmic. Extremely long half-life (40-55 days). TdP risk is paradoxically lower than expected due to multi-channel block.", citation: "Goldfrank 11th ed Ch 64" } }
    if name == "SOTALOL" { return QTDrug { name: "Sotalol", risk_category: "Known TdP risk", typical_qtc_prolongation_ms: 40.0, mechanism: "Pure IKr blocker + beta-blocker. Dose-dependent QT prolongation. TdP risk 2-4% at therapeutic doses. Higher risk with renal impairment (renally cleared).", citation: "Goldfrank 11th ed Ch 64" } }
    if name == "HALOPERIDOL" { return QTDrug { name: "Haloperidol", risk_category: "Known TdP risk", typical_qtc_prolongation_ms: 15.0, mechanism: "IKr blockade. Risk highest with IV administration (which is off-label). Dose-dependent. FDA black box warning for IV use.", citation: "Goldfrank 11th ed Ch 70" } }
    if name == "METHADONE" { return QTDrug { name: "Methadone", risk_category: "Known TdP risk", typical_qtc_prolongation_ms: 20.0, mechanism: "IKr blockade. Risk increases above 100 mg/day. Baseline and follow-up ECGs recommended. CYP3A4 interactions increase levels and QT risk.", citation: "Goldfrank 11th ed Ch 38" } }
    if name == "ONDANSETRON" { return QTDrug { name: "Ondansetron", risk_category: "Known TdP risk", typical_qtc_prolongation_ms: 20.0, mechanism: "IKr blockade. FDA limited single IV dose to 16 mg (2012). Dose-dependent QT prolongation. Use granisetron as alternative if QT concerns.", citation: "Goldfrank 11th ed Ch 16" } }
    if name == "ERYTHROMYCIN" { return QTDrug { name: "Erythromycin", risk_category: "Known TdP risk", typical_qtc_prolongation_ms: 15.0, mechanism: "IKr blockade. Also inhibits CYP3A4, increasing levels of co-administered QT-prolonging drugs. IV erythromycin carries highest risk.", citation: "Goldfrank 11th ed Ch 16" } }
    if name == "FLUOROQUINOLONES" { return QTDrug { name: "Fluoroquinolones (moxifloxacin > levofloxacin > ciprofloxacin)", risk_category: "Known/Conditional TdP risk", typical_qtc_prolongation_ms: 10.0, mechanism: "IKr blockade. Moxifloxacin has the strongest QT effect. Ciprofloxacin has the least. Levofloxacin is intermediate.", citation: "Goldfrank 11th ed Ch 16" } }
    if name == "DROPERIDOL" { return QTDrug { name: "Droperidol", risk_category: "Known TdP risk", typical_qtc_prolongation_ms: 15.0, mechanism: "IKr blockade. FDA black box warning (2001) led to dramatic decline in use despite minimal TdP at antiemetic doses (0.625-1.25 mg).", citation: "Goldfrank 11th ed Ch 16" } }
    if name == "THIORIDAZINE" { return QTDrug { name: "Thioridazine", risk_category: "Known TdP risk", typical_qtc_prolongation_ms: 35.0, mechanism: "Among the strongest IKr blockers of any antipsychotic. Dose-dependent QT prolongation. Removed from first-line due to cardiac risk. Maximum dose 800 mg/day.", citation: "Goldfrank 11th ed Ch 70" } }
    if name == "CHLOROQUINE" { return QTDrug { name: "Chloroquine / Hydroxychloroquine", risk_category: "Known TdP risk", typical_qtc_prolongation_ms: 15.0, mechanism: "IKr blockade. Risk increases with overdose. QT prolongation contributed to safety concerns during COVID-19 use. Cumulative cardiac toxicity with chronic use.", citation: "Goldfrank 11th ed Ch 58" } }
    return QTDrug { name: name, risk_category: "Unknown -- consult CredibleMeds.org", typical_qtc_prolongation_ms: 0.0, mechanism: "Drug not in local database. Check CredibleMeds.org for risk classification.", citation: "CredibleMeds.org" }
}


// ==========================================================
// SECTION FOUR: TOXIDROMES
// ==========================================================
//
// A toxidrome is a constellation of signs and symptoms that
// suggests a specific class of poisoning. Pattern recognition
// of toxidromes is the foundation of clinical toxicology.
//
// Goldfrank's 11th ed, Ch 3: Initial Evaluation of the Patient.
// Casarett and Doull's 9th ed, Ch 34: Clinical Toxicology.

fn toxidrome(name: String) -> Toxidrome {
    if name == "ANTICHOLINERGIC" {
        return Toxidrome {
            name: "Anticholinergic (antimuscarinic)",
            vital_signs: "Tachycardia, hypertension, hyperthermia",
            pupils: "Mydriasis (dilated), non-reactive",
            skin: "Dry, flushed, hot (anhidrotic) -- 'red as a beet, dry as a bone, hot as a hare'",
            mental_status: "Agitated delirium, hallucinations (especially visual -- 'picking at things'), mumbling -- 'mad as a hatter'",
            other_findings: "Urinary retention ('full as a flask'), decreased bowel sounds ('slow as a snail'), myoclonus, seizures in severe cases",
            treatment: "Physostigmine 1-2 mg IV slow push (reversal agent for pure anticholinergic -- NOT for TCA). Benzodiazepines for agitation/seizures. Cooling measures for hyperthermia. Foley for urinary retention.",
            prototype_drugs: "Diphenhydramine, atropine, scopolamine, Jimson weed (Datura), TCAs, antihistamines, cyclobenzaprine",
            citation: "Goldfrank 11th ed Ch 3, Ch 73"
        }
    }
    if name == "CHOLINERGIC" {
        return Toxidrome {
            name: "Cholinergic (muscarinic + nicotinic)",
            vital_signs: "Bradycardia (muscarinic) -- can be tachycardic early (nicotinic), hypotension",
            pupils: "Miosis (constricted)",
            skin: "Diaphoretic (sweating profusely), wet",
            mental_status: "Confusion, anxiety, coma in severe cases",
            other_findings: "DUMBBBELS: Diarrhea, Urination, Miosis, Bradycardia/Bronchospasm/Bronchorrhea, Emesis, Lacrimation, Salivation. KILLER Bs: Bradycardia, Bronchospasm, Bronchorrhea. Fasciculations (nicotinic).",
            treatment: "Atropine 2-4 mg IV, double dose q5 min until secretions dry (may need massive doses: 100+ mg for organophosphates). Pralidoxime (2-PAM) 1-2g IV for organophosphates (reactivates acetylcholinesterase before aging). Benzodiazepines for seizures.",
            prototype_drugs: "Organophosphates (malathion, parathion, sarin), carbamates (physostigmine, neostigmine), nerve agents (VX, soman)",
            citation: "Goldfrank 11th ed Ch 3, Ch 113"
        }
    }
    if name == "SYMPATHOMIMETIC" {
        return Toxidrome {
            name: "Sympathomimetic (adrenergic)",
            vital_signs: "Tachycardia, hypertension, hyperthermia, tachypnea",
            pupils: "Mydriasis (dilated), reactive",
            skin: "Diaphoretic (sweating), warm",
            mental_status: "Agitation, euphoria, paranoia, psychosis, seizures",
            other_findings: "Tremor, hyperreflexia, rhabdomyolysis, myocardial ischemia/infarction, intracranial hemorrhage, metabolic acidosis. Chest pain common.",
            treatment: "Benzodiazepines are FIRST LINE for agitation, seizures, hypertension, and tachycardia. Avoid beta-blockers (unopposed alpha stimulation). Nitroprusside or phentolamine for refractory hypertension. Active cooling for hyperthermia.",
            prototype_drugs: "Cocaine, amphetamines, methamphetamine, MDMA, ephedrine, pseudoephedrine, synthetic cathinones (bath salts)",
            citation: "Goldfrank 11th ed Ch 3, Ch 76-78"
        }
    }
    if name == "OPIOID" {
        return Toxidrome {
            name: "Opioid",
            vital_signs: "Bradycardia, hypotension, hypothermia, respiratory depression (< 12 breaths/min)",
            pupils: "Miosis (pinpoint) -- classic triad: CNS depression + respiratory depression + miosis",
            skin: "Cool, pale",
            mental_status: "CNS depression ranging from sedation to coma. Decreased respiratory drive is the cause of death.",
            other_findings: "Decreased bowel sounds (ileus), pulmonary edema (heroin, methadone), needle marks. Exception: meperidine causes mydriasis and seizures. Propoxyphene causes wide QRS.",
            treatment: "Naloxone (Narcan) 0.04-0.4 mg IV initial dose (titrate to respiratory rate > 12, not full consciousness -- avoid precipitating withdrawal). May need repeat dosing (naloxone half-life 30-90 min < most opioid half-lives). Bag-valve-mask ventilation while preparing naloxone.",
            prototype_drugs: "Heroin, morphine, fentanyl, oxycodone, hydrocodone, methadone, codeine, carfentanil",
            citation: "Goldfrank 11th ed Ch 3, Ch 38"
        }
    }
    if name == "SEDATIVE_HYPNOTIC" {
        return Toxidrome {
            name: "Sedative-hypnotic",
            vital_signs: "Bradycardia, hypotension, hypothermia, respiratory depression",
            pupils: "Mid-position or miosis (variable)",
            skin: "Normal or cool",
            mental_status: "CNS depression: slurred speech, ataxia, sedation, coma. Less respiratory depression than opioids at therapeutic doses.",
            other_findings: "Hyporeflexia, nystagmus. Benzodiazepines rarely cause death alone (wide safety margin) but lethal with co-ingestants (opioids, alcohol). Barbiturates have narrow safety margin and cause cardiovascular collapse in overdose.",
            treatment: "Supportive care is the mainstay. Flumazenil 0.2 mg IV for pure benzodiazepine overdose ONLY (contraindicated if chronic benzo use, co-ingested TCA or seizure-prone drugs -- risk of precipitating seizures). Intubation if needed. No barbiturate reversal agent.",
            prototype_drugs: "Benzodiazepines (diazepam, lorazepam, alprazolam, midazolam), barbiturates (phenobarbital), zolpidem, GHB, ethanol",
            citation: "Goldfrank 11th ed Ch 3, Ch 33"
        }
    }
    if name == "SEROTONIN_SYNDROME" {
        return Toxidrome {
            name: "Serotonin syndrome",
            vital_signs: "Tachycardia, hypertension, hyperthermia (can be > 41C / 106F)",
            pupils: "Mydriasis (dilated)",
            skin: "Diaphoretic, flushed",
            mental_status: "Agitation, confusion, delirium, coma in severe cases",
            other_findings: "Hunter criteria: CLONUS (spontaneous, inducible, or ocular) is the hallmark. Also: hyperreflexia, muscle rigidity (lower > upper extremities), tremor, ataxia, diarrhea. Onset usually within 24 hours of drug change. Differs from NMS by rapid onset and clonus.",
            treatment: "STOP all serotonergic agents. Cyproheptadine 12 mg PO initial then 4 mg q2h (5-HT2A antagonist -- SPECIFIC antidote). Benzodiazepines for agitation/muscle rigidity. Active cooling for hyperthermia. Avoid succinylcholine (rhabdomyolysis risk). Supportive care.",
            prototype_drugs: "SSRIs, SNRIs, MAOIs, tramadol, meperidine, linezolid, fentanyl, St John's wort, dextromethorphan, triptans. DANGEROUS COMBOS: MAOI + SSRI, MAOI + meperidine",
            citation: "Goldfrank 11th ed Ch 3, Ch 72; Boyer EW, Shannon M. NEJM 352:1112, 2005"
        }
    }
    if name == "NMS" {
        return Toxidrome {
            name: "Neuroleptic malignant syndrome (NMS)",
            vital_signs: "Hyperthermia (often > 40C / 104F), tachycardia, labile blood pressure, tachypnea",
            pupils: "Normal (not typically affected)",
            skin: "Diaphoretic, pallid",
            mental_status: "Altered consciousness: confusion progressing to coma. 'Lead pipe' rigidity is hallmark.",
            other_findings: "FOUR cardinal features: (i) altered mental status, (ii) muscle rigidity ('lead pipe'), (iii) hyperthermia, (iv) autonomic instability. Elevated CPK (often > 1000 U/L from rhabdomyolysis). Leukocytosis. Metabolic acidosis. Onset over DAYS (unlike serotonin syndrome which is hours). Mortality 10-20% without treatment.",
            treatment: "STOP offending neuroleptic. Dantrolene 1-2.5 mg/kg IV (skeletal muscle relaxant). Bromocriptine 2.5 mg PO/NG q8h (dopamine agonist). Aggressive cooling. IV fluids for rhabdomyolysis. Benzodiazepines for muscle rigidity. ICU admission. Monitor CPK, renal function.",
            prototype_drugs: "Haloperidol, droperidol, chlorpromazine, fluphenazine, risperidone, olanzapine. Also: rapid withdrawal of dopamine agonists (levodopa, amantadine) in Parkinson's disease.",
            citation: "Goldfrank 11th ed Ch 3, Ch 70; Strawn JR et al. Am J Psychiatry 164:870, 2007"
        }
    }
    return Toxidrome {
        name: name,
        vital_signs: "Unknown toxidrome",
        pupils: "",
        skin: "",
        mental_status: "",
        other_findings: "Toxidrome not recognized. Known toxidromes: ANTICHOLINERGIC, CHOLINERGIC, SYMPATHOMIMETIC, OPIOID, SEDATIVE_HYPNOTIC, SEROTONIN_SYNDROME, NMS",
        treatment: "",
        prototype_drugs: "",
        citation: ""
    }
}


// ==========================================================
// SECTION FIVE: ANTIDOTES
// ==========================================================
//
// Specific antidotes exist for only a minority of poisonings.
// Supportive care (airway, breathing, circulation) remains the
// foundation of toxicologic management for all poisonings.
//
// Goldfrank's 11th ed, Part A: The General Approach to the
//   Poisoned Patient; individual antidote chapters throughout.
// Casarett and Doull's 9th ed, Ch 34: Clinical Toxicology.

fn antidote(poison: String) -> AntidoteEntry {
    if poison == "ACETAMINOPHEN" {
        return AntidoteEntry {
            poison: "Acetaminophen (paracetamol)",
            antidote: "N-acetylcysteine (NAC, Acetadote, Mucomyst)",
            mechanism_of_antidote: "Replenishes hepatic glutathione stores, provides sulfhydryl groups to conjugate NAPQI (toxic metabolite), enhances sulfation pathway. At toxic doses, CYP2E1 converts acetaminophen to NAPQI which depletes glutathione and causes centrilobular hepatic necrosis.",
            dosing: "IV 21-hour protocol: 150 mg/kg in 200 mL D5W over 60 min, then 50 mg/kg in 500 mL D5W over 4 hours, then 100 mg/kg in 1000 mL D5W over 16 hours. Oral 72-hour protocol: 140 mg/kg loading, then 70 mg/kg q4h x 17 additional doses.",
            time_window: "Most effective within 8 hours of ingestion. Still beneficial up to 24-36 hours. Initiate before Rumack-Matthew nomogram result if level will be delayed.",
            monitoring: "Acetaminophen level at 4 hours post-ingestion (or on presentation if > 4h). AST, ALT, INR, creatinine, bilirubin q12-24h. If INR > 2 or ALT rising, continue NAC beyond 21 hours.",
            citation: "Goldfrank 11th ed Ch 35; Prescott LF. BMJ 2:1097, 1979"
        }
    }
    if poison == "OPIOID" {
        return AntidoteEntry {
            poison: "Opioids (heroin, morphine, fentanyl, oxycodone, etc.)",
            antidote: "Naloxone (Narcan)",
            mechanism_of_antidote: "Competitive mu-opioid receptor antagonist. Displaces opioid from receptor. Reverses CNS depression, respiratory depression, and miosis within 1-2 minutes IV.",
            dosing: "0.04 mg IV initial dose for known opioid users (titrate up). 0.4-2 mg IV for non-opioid-dependent patients. May repeat q2-3 min to max 10 mg. IM/IN/SC if no IV access (onset 3-5 min). Continuous infusion: 2/3 of effective bolus dose per hour.",
            time_window: "Immediate. Naloxone half-life 30-90 min -- shorter than most opioids. MUST observe for re-sedation. Methadone/buprenorphine poisoning may need prolonged infusion or repeated dosing.",
            monitoring: "Respiratory rate (target > 12/min), SpO2, level of consciousness. Watch for re-sedation. Watch for precipitated withdrawal in chronic users (not life-threatening but distressing).",
            citation: "Goldfrank 11th ed Ch 38"
        }
    }
    if poison == "BENZODIAZEPINE" {
        return AntidoteEntry {
            poison: "Benzodiazepines (diazepam, lorazepam, alprazolam, midazolam)",
            antidote: "Flumazenil (Romazicon)",
            mechanism_of_antidote: "Competitive GABA-A benzodiazepine site antagonist. Reverses sedation, respiratory depression, and amnesia from benzodiazepines.",
            dosing: "0.2 mg IV over 30 seconds. May repeat 0.3 mg after 30 seconds, then 0.5 mg q1min to max 3-5 mg total.",
            time_window: "CAUTION: Contraindicated in (i) chronic benzodiazepine use (precipitates withdrawal seizures), (ii) co-ingestion with TCA or other seizure-causing drugs, (iii) seizure disorder controlled with benzodiazepines. Duration 45-90 min. Re-sedation common.",
            monitoring: "Level of consciousness, seizure watch, respiratory status. Must observe for re-sedation (most benzos outlast flumazenil).",
            citation: "Goldfrank 11th ed Ch 33"
        }
    }
    if poison == "ORGANOPHOSPHATE" {
        return AntidoteEntry {
            poison: "Organophosphates (malathion, parathion, sarin, VX)",
            antidote: "Atropine + Pralidoxime (2-PAM)",
            mechanism_of_antidote: "Atropine: competitive muscarinic antagonist. Reverses DUMBBBELS symptoms. Does NOT reverse nicotinic effects (fasciculations, paralysis). Pralidoxime: reactivates acetylcholinesterase BEFORE 'aging' (permanent enzyme inactivation). Aging time varies: soman minutes, VX hours, parathion days.",
            dosing: "Atropine: 2-4 mg IV, double q5 min until secretions dry (may need 100+ mg). Endpoint: DRY bronchial secretions, not pupil size or heart rate. Pralidoxime: 1-2 g IV over 15-30 min, then 500 mg/h infusion. Must give within aging window.",
            time_window: "Atropine: immediate and ongoing. Pralidoxime: ideally within 24 hours for most organophosphates. Ineffective after aging occurs. Give both simultaneously.",
            monitoring: "Cholinesterase levels (RBC and plasma). Secretion management. Intermediate syndrome (weakness 24-96 hours). Delayed neuropathy (2-4 weeks, organophosphate-induced delayed polyneuropathy).",
            citation: "Goldfrank 11th ed Ch 113; Eddleston M et al. Lancet 371:597, 2008"
        }
    }
    if poison == "DIGOXIN" {
        return AntidoteEntry {
            poison: "Digoxin / cardiac glycosides (digitalis, oleander, foxglove, lily of the valley, toad venom/bufotoxin)",
            antidote: "Digoxin-specific antibody fragments (DigiFab, formerly Digibind)",
            mechanism_of_antidote: "Fab fragments bind free digoxin, preventing Na/K-ATPase inhibition. Redistributes digoxin from tissues to plasma (bound to Fab), then renally excreted. Onset 20-30 minutes IV.",
            dosing: "Empiric: 10-20 vials for acute life-threatening ingestion. Calculated: number of vials = (serum digoxin ng/mL x weight kg) / 100. For chronic toxicity: 1-2 vials often sufficient.",
            time_window: "Immediate for: hyperkalemia > 5.5 with digoxin, hemodynamically unstable bradycardia, ventricular arrhythmias. NOT for asymptomatic elevated levels.",
            monitoring: "Potassium (falls rapidly after DigiFab as Na/K-ATPase resumes). Cardiac rhythm. Note: total serum digoxin level rises after DigiFab (Fab-bound digoxin detected by assay but not pharmacologically active). Free digoxin level is the meaningful measurement.",
            citation: "Goldfrank 11th ed Ch 65"
        }
    }
    if poison == "WARFARIN" {
        return AntidoteEntry {
            poison: "Warfarin / vitamin K antagonists (brodifacoum, superwarfarins)",
            antidote: "Vitamin K1 (phytonadione) + Fresh Frozen Plasma (FFP) + Prothrombin Complex Concentrate (PCC, 4-factor preferred)",
            mechanism_of_antidote: "Vitamin K1: bypasses warfarin blockade of vitamin K epoxide reductase (VKORC1). Restores synthesis of factors II, VII, IX, X (takes 6-24 hours). FFP/PCC: immediately replaces depleted clotting factors. 4-factor PCC (Kcentra) preferred over FFP (faster, smaller volume, no blood type needed).",
            dosing: "Vitamin K1: 10 mg IV slow infusion (risk of anaphylactoid reaction if given too fast). PCC (4-factor): 25-50 units/kg IV. FFP: 10-15 mL/kg. Superwarfarin (brodifacoum): vitamin K1 50-200 mg/day PO for MONTHS (half-life up to 56 days).",
            time_window: "PCC/FFP: immediate for active bleeding or INR > 10. Vitamin K: give simultaneously but takes hours to work. Superwarfarins require prolonged treatment with serial INR monitoring.",
            monitoring: "INR q6h initially, then daily. CBC for bleeding. PT/INR should normalize within 6-8 hours of PCC. Vitamin K effect takes 12-24 hours. For superwarfarins, check INR 48 hours after stopping vitamin K to ensure it stays normal.",
            citation: "Goldfrank 11th ed Ch 60"
        }
    }
    if poison == "METHANOL" {
        return AntidoteEntry {
            poison: "Methanol (wood alcohol) / Ethylene glycol (antifreeze)",
            antidote: "Fomepizole (Antizol) -- preferred. Ethanol (alternative if fomepizole unavailable).",
            mechanism_of_antidote: "Both inhibit alcohol dehydrogenase (ADH), preventing conversion of methanol to formic acid (causes blindness) or ethylene glycol to glycolic/oxalic acid (causes renal failure and calcium oxalate crystalluria). Fomepizole: specific ADH inhibitor, easier to dose, no CNS depression.",
            dosing: "Fomepizole: 15 mg/kg IV loading, then 10 mg/kg q12h x 4 doses, then 15 mg/kg q12h until levels undetectable. During dialysis: q4h dosing. Ethanol: target blood ethanol 100-150 mg/dL (loading 0.8 g/kg IV then 80-130 mg/kg/h).",
            time_window: "ASAP. Begin if osmol gap > 10 or suspicion of ingestion. Do not wait for levels. Hemodialysis indicated if: pH < 7.25, visual symptoms (methanol), renal failure (ethylene glycol), level > 50 mg/dL.",
            monitoring: "Serum methanol/ethylene glycol levels. Osmol gap (decreases as parent compound metabolized). Anion gap metabolic acidosis. Lactate. For methanol: fundoscopic exam (disc hyperemia = retinal toxicity). For ethylene glycol: urinalysis for calcium oxalate crystals, calcium level.",
            citation: "Goldfrank 11th ed Ch 109-110; Brent J et al. NEJM 344:424, 2001"
        }
    }
    if poison == "ETHYLENE_GLYCOL" {
        return AntidoteEntry {
            poison: "Ethylene glycol (antifreeze)",
            antidote: "Fomepizole (Antizol) -- preferred. Ethanol (alternative).",
            mechanism_of_antidote: "Inhibits alcohol dehydrogenase, preventing conversion to glycolaldehyde, glycolic acid, glyoxylic acid, and oxalic acid. Oxalate combines with calcium forming calcium oxalate crystals causing renal tubular obstruction and hypocalcemia.",
            dosing: "Fomepizole: 15 mg/kg IV loading, then 10 mg/kg q12h x 4 doses, then 15 mg/kg q12h. Hemodialysis for pH < 7.3, renal failure, or level > 50 mg/dL.",
            time_window: "Immediate. Three stages: (i) 0-12h CNS depression/inebriation, (ii) 12-24h cardiopulmonary (metabolic acidosis, tachycardia), (iii) 24-72h renal failure (oliguria, flank pain, calcium oxalate crystals).",
            monitoring: "Ethylene glycol level, osmol gap, anion gap, calcium, renal function, urine microscopy for calcium oxalate crystals (envelope-shaped = monohydrate, needle-shaped = dihydrate).",
            citation: "Goldfrank 11th ed Ch 110"
        }
    }
    if poison == "IRON" {
        return AntidoteEntry {
            poison: "Iron (ferrous sulfate, ferrous gluconate, prenatal vitamins)",
            antidote: "Deferoxamine (Desferal)",
            mechanism_of_antidote: "Iron chelator produced by Streptomyces pilosus. Binds free iron (Fe3+) to form ferrioxamine, which is renally excreted (vin rose colored urine). Does not remove transferrin-bound iron. Chelates mitochondrial iron preventing oxidative damage.",
            dosing: "15 mg/kg/h IV continuous infusion (max 6-8 g/day). Continue until clinical improvement, anion gap normalizes, and urine color normalizes. Typical duration 24-48 hours. Do NOT exceed 24 hours if possible (risk of ARDS with prolonged use).",
            time_window: "Indications: serum iron > 500 mcg/dL, metabolic acidosis, shock, or severe GI symptoms. Five stages: (i) 0-6h GI (vomiting, diarrhea, GI hemorrhage), (ii) 6-24h apparent improvement (latent period), (iii) 12-48h shock/organ failure, (iv) 2-5 days hepatic failure, (v) 2-6 weeks GI strictures.",
            monitoring: "Serum iron level (> 500 = severe). TIBC is unreliable in overdose. Metabolic acidosis (AG). Abdominal XR (iron tablets are radiopaque). Urine color (vin rose). WBI for tablet concretions.",
            citation: "Goldfrank 11th ed Ch 46"
        }
    }
    if poison == "CYANIDE" {
        return AntidoteEntry {
            poison: "Cyanide (hydrogen cyanide gas, cyanide salts, nitroprusside toxicity, smoke inhalation)",
            antidote: "Hydroxocobalamin (Cyanokit) -- preferred. Sodium thiosulfate (alternative/adjunct). Nitrite-thiosulfate kit (amyl/sodium nitrite + thiosulfate) is older option.",
            mechanism_of_antidote: "Hydroxocobalamin: cobalt in vitamin B12 precursor directly binds cyanide forming cyanocobalamin (vitamin B12), renally excreted. Does not cause methemoglobinemia. Safe in smoke inhalation. Thiosulfate: provides sulfur donor for rhodanese enzyme to convert cyanide to thiocyanate.",
            dosing: "Hydroxocobalamin: 5 g IV over 15 min (may repeat once). Sodium thiosulfate: 12.5 g IV. Nitrite-thiosulfate kit: amyl nitrite inhaled, then sodium nitrite 300 mg IV (forms methemoglobin which binds cyanide), then thiosulfate. AVOID nitrites if concurrent CO exposure.",
            time_window: "IMMEDIATE. Cyanide kills within minutes by inhibiting cytochrome oxidase (Complex IV), halting aerobic metabolism. Lactic acidosis with high mixed venous O2 is classic.",
            monitoring: "Lactic acid, ABG/VBG (narrow A-a gradient is clue -- venous blood is bright red because O2 cannot be used). Whole blood cyanide level if available (> 1 mg/L toxic). Methemoglobin level if nitrites used. Note: hydroxocobalamin causes red discoloration of skin, urine, and mucous membranes (not a toxic effect) and interferes with many lab colorimetric assays.",
            citation: "Goldfrank 11th ed Ch 126"
        }
    }
    if poison == "BETA_BLOCKER" {
        return AntidoteEntry {
            poison: "Beta-adrenergic blockers (propranolol, metoprolol, atenolol, carvedilol, etc.)",
            antidote: "Glucagon (first-line). High-dose insulin euglycemia (HDIE) therapy. IV lipid emulsion for lipophilic agents.",
            mechanism_of_antidote: "Glucagon: activates adenylate cyclase via glucagon receptor (independent of beta receptor), increasing cAMP, enhancing inotropy and chronotropy. Bypasses beta-receptor blockade. HDIE: insulin is a potent inotrope at high doses via increased myocardial glucose uptake.",
            dosing: "Glucagon: 3-10 mg IV bolus, then 3-5 mg/h infusion. May cause vomiting (position patient to avoid aspiration). HDIE: insulin 1 unit/kg IV bolus then 0.5-1 unit/kg/h, with dextrose 0.5 g/kg/h to maintain glucose 100-200. Potassium monitoring essential.",
            time_window: "Immediate for symptomatic bradycardia, hypotension, or cardiogenic shock. Propranolol is the most dangerous (sodium channel blockade causing wide QRS + membrane-stabilizing effect + lipophilic = CNS effects/seizures).",
            monitoring: "Heart rate, blood pressure, glucose q15-30 min with HDIE, potassium q1h. ECG for conduction abnormalities. Propranolol: watch for seizures and wide QRS.",
            citation: "Goldfrank 11th ed Ch 62"
        }
    }
    if poison == "TCA" {
        return AntidoteEntry {
            poison: "Tricyclic antidepressants (amitriptyline, nortriptyline, imipramine, desipramine)",
            antidote: "Sodium bicarbonate (8.4% solution)",
            mechanism_of_antidote: "Sodium bicarbonate reverses TCA cardiotoxicity by: (i) sodium load overcomes fast sodium channel blockade (narrows QRS), (ii) alkalinization reduces free TCA by increasing protein binding, (iii) alkalinization favors non-ionized form (less channel binding). Target serum pH 7.45-7.55.",
            dosing: "1-2 mEq/kg IV bolus for QRS > 100 ms or ventricular arrhythmias. Repeat q3-5 min until QRS narrows. Then continuous infusion: 150 mEq NaHCO3 in 1L D5W at 150-250 mL/h to maintain pH 7.45-7.55.",
            time_window: "Immediate for: QRS > 100 ms, R wave > 3 mm in aVR, ventricular arrhythmias, hypotension, or seizures. TCA toxicity is rapidly lethal (can seize and arrest within 1-2 hours of ingestion).",
            monitoring: "Continuous ECG (QRS duration, R wave in aVR, QTc). ABG for pH. Electrolytes (hypernatremia, hypokalemia from bicarb). Level of consciousness. Seizures (treat with benzodiazepines, NOT phenytoin). Do NOT give flumazenil (may precipitate seizures).",
            citation: "Goldfrank 11th ed Ch 71; Liebelt EL. Clin Toxicol 49:299, 2011"
        }
    }
    if poison == "HEPARIN" {
        return AntidoteEntry {
            poison: "Heparin (unfractionated) / LMWH (enoxaparin, partial reversal only)",
            antidote: "Protamine sulfate",
            mechanism_of_antidote: "Protamine is a positively charged protein (from salmon sperm) that binds negatively charged heparin, forming inactive salt complex. Fully reverses unfractionated heparin (UFH). Only 60% reversal of LMWH anti-Xa activity (does not bind low molecular weight fragments).",
            dosing: "1 mg protamine per 100 units UFH given in prior 2-3 hours. Max single dose 50 mg. Give IV slowly over 10 min (rapid infusion causes hypotension, bradycardia, anaphylactoid reaction). For LMWH: 1 mg protamine per 1 mg enoxaparin if within 8 hours.",
            time_window: "Immediate for life-threatening bleeding. Heparin half-life is 60-90 min, so amount to reverse decreases over time. If heparin given > 2 hours ago, reduce protamine dose by 50%.",
            monitoring: "aPTT (for UFH), anti-Xa activity (for LMWH). Watch for heparin rebound (aPTT re-elevation 2-4 hours later as protamine cleared). Monitor for protamine reactions (especially in NPH insulin users and fish allergy -- protamine derived from fish).",
            citation: "Goldfrank 11th ed Ch 60"
        }
    }
    return AntidoteEntry {
        poison: poison,
        antidote: "No specific antidote in local database",
        mechanism_of_antidote: "Poison not recognized. Known poisons: ACETAMINOPHEN, OPIOID, BENZODIAZEPINE, ORGANOPHOSPHATE, DIGOXIN, WARFARIN, METHANOL, ETHYLENE_GLYCOL, IRON, CYANIDE, BETA_BLOCKER, TCA, HEPARIN",
        dosing: "",
        time_window: "Contact Poison Control Center: 1-800-222-1222 (US)",
        monitoring: "",
        citation: ""
    }
}


// ==========================================================
// SECTION SIX: RUCAM SCORE (Roussel Uclaf Causality Assessment)
// ==========================================================
//
// RUCAM is the validated instrument for assessing causality in
// drug-induced liver injury (DILI). Scores range from -3 to +14.
//
// Danan G, Benichou C. J Clin Epidemiol 46:1323-1330, 1993.
// Goldfrank 11th ed Ch 26: Hepatic Principles.
//
// Parameters:
//   time_to_onset: 1 = suggestive (5-90 days), 2 = compatible, 0 = against
//   course_after_cessation: 1 = suggestive (>50% decrease in 8 days),
//     2 = highly suggestive, 0 = against
//   risk_factors: 1 = alcohol/age present, 0 = absent
//   concomitant_drugs: 0 = none, -1 = possible role, -2 = probable role
//   exclusion_of_other_causes: 2 = all excluded, 1 = most excluded,
//     0 = some alternatives, -1 = probable non-drug cause
//   previous_info_on_drug: 2 = reaction labeling, 1 = published case reports,
//     0 = unknown
//   rechallenge: 3 = positive, 1 = compatible, 0 = not done, -2 = negative
fn rucam_score(time_to_onset: Int, course_after_cessation: Int, risk_factors: Int, concomitant_drugs: Int, exclusion_of_other_causes: Int, previous_info_on_drug: Int, rechallenge: Int) -> String {
    let total = time_to_onset + course_after_cessation + risk_factors + concomitant_drugs + exclusion_of_other_causes + previous_info_on_drug + rechallenge
    if total >= 9 { return "HIGHLY PROBABLE (RUCAM >= 9): Drug-induced liver injury is highly probable. Strongest level of causality. Danan G, Benichou C. J Clin Epidemiol 1993." }
    if total >= 6 { return "PROBABLE (RUCAM 6-8): Drug-induced liver injury is probable. Strong evidence of causal relationship. Monitor closely, avoid re-exposure." }
    if total >= 3 { return "POSSIBLE (RUCAM 3-5): Drug-induced liver injury is possible but other causes not fully excluded. Further workup needed." }
    if total >= 1 { return "UNLIKELY (RUCAM 1-2): Drug-induced liver injury unlikely. Consider alternative diagnoses (viral hepatitis, autoimmune, ischemic, etc.)." }
    return "EXCLUDED (RUCAM <= 0): Drug-induced liver injury excluded by RUCAM criteria. Investigate other causes."
}

// DILI pattern classification based on R-value
// R = (ALT / ALT_ULN) / (ALP / ALP_ULN)
// R >= 5 = hepatocellular, R 2-5 = mixed, R < 2 = cholestatic
fn dili_pattern(alt: Float, alt_uln: Float, alp: Float, alp_uln: Float) -> String {
    let r_value = (alt / alt_uln) / (alp / alp_uln)
    if r_value >= 5.0 { return "HEPATOCELLULAR pattern (R >= 5). Predominant hepatocyte necrosis. Examples: acetaminophen, isoniazid, diclofenac, valproic acid. Higher risk of acute liver failure. Apply Hy's Law criteria." }
    if r_value >= 2.0 { return "MIXED pattern (R 2-5). Both hepatocellular and cholestatic features. Examples: phenytoin, amoxicillin-clavulanate, sulfonamides. Intermediate prognosis." }
    return "CHOLESTATIC pattern (R < 2). Predominant bile duct/canalicular injury. Examples: chlorpromazine, erythromycin, anabolic steroids, oral contraceptives. Generally better prognosis. May take months to resolve."
}


// ==========================================================
// SECTION SEVEN: ACETAMINOPHEN TOXICITY
// ==========================================================
//
// Acetaminophen (APAP) is the most common cause of acute liver
// failure in the US and UK. At therapeutic doses, > 90% is
// conjugated by glucuronidation and sulfation. At toxic doses,
// these pathways saturate, and CYP2E1 produces NAPQI, which
// depletes glutathione and causes centrilobular necrosis.
//
// Goldfrank 11th ed, Ch 35: Acetaminophen.
// Rumack BH, Matthew H. Pediatrics 55:871-876, 1975.

// Rumack-Matthew nomogram assessment
// Treatment line starts at 150 mcg/mL at 4 hours and drops to
// approximately 4.7 mcg/mL at 24 hours (log-linear).
//
// Treatment line equation (semi-log):
// Treatment level at time t = 150 * 10^(-(t - 4) * log10(150/4.7) / 20)
//
// Simplified: treatment_level = 150 * exp(-0.174 * (t - 4))
// This is the original Rumack line (150-line).
//
// Only valid 4-24 hours post single acute ingestion.
fn rumack_matthew(apap_level: Float, hours_post_ingestion: Float) -> String {
    if hours_post_ingestion < 4.0 { return "TOO EARLY: Level drawn before 4 hours is unreliable. Absorption may be incomplete. Redraw at 4 hours. If massive ingestion suspected, begin NAC empirically." }
    if hours_post_ingestion > 24.0 { return "BEYOND NOMOGRAM: Level drawn after 24 hours. Nomogram is not validated after 24 hours. Check AST/ALT, INR, creatinine. Treat with NAC if ANY evidence of liver injury regardless of level." }
    // Treatment line: 150 mcg/mL at 4h, declining log-linearly
    // treatment_level = 150 * exp(-0.174 * (hours - 4))
    let exponent = 0.0 - 0.174 * (hours_post_ingestion - 4.0)
    let treatment_line = 150.0 * exp(exponent)
    if apap_level > treatment_line { return "ABOVE TREATMENT LINE: Acetaminophen level is ABOVE the Rumack-Matthew 150-line. HIGH RISK of hepatotoxicity. BEGIN NAC IMMEDIATELY. IV NAC preferred. Draw baseline AST, ALT, INR, creatinine, bilirubin." }
    // Check if close to the line (within 25%)
    let close_threshold = treatment_line * 0.75
    if apap_level > close_threshold { return "BELOW BUT NEAR TREATMENT LINE: Level is below but within 25% of the treatment line. Consider NAC if: co-ingestants delay absorption, time of ingestion uncertain, chronic alcohol use, CYP2E1-inducing medications, or malnutrition/fasting (depleted glutathione)." }
    return "BELOW TREATMENT LINE: Level is well below the Rumack-Matthew treatment line. Low risk of hepatotoxicity from this single ingestion. No NAC indicated for an acute single ingestion in the absence of risk factors. Monitor clinically."
}

// NAC IV protocol (21-hour 3-bag Prescott protocol)
// The most commonly used modern protocol.
// Goldfrank 11th ed Ch 35; Prescott LF. BMJ 1979.
fn nac_protocol(weight_kg: Float) -> NACProtocol {
    // Bag 1: 150 mg/kg in 200 mL D5W over 60 minutes
    let bag1_dose = 150.0 * weight_kg
    // Bag 2: 50 mg/kg in 500 mL D5W over 4 hours (240 min)
    let bag2_dose = 50.0 * weight_kg
    // Bag 3: 100 mg/kg in 1000 mL D5W over 16 hours (960 min)
    let bag3_dose = 100.0 * weight_kg
    let total = bag1_dose + bag2_dose + bag3_dose
    return NACProtocol {
        weight_kg: weight_kg,
        bag_one_dose_mg: bag1_dose,
        bag_one_volume_ml: 200.0,
        bag_one_duration_min: 60.0,
        bag_two_dose_mg: bag2_dose,
        bag_two_volume_ml: 500.0,
        bag_two_duration_min: 240.0,
        bag_three_dose_mg: bag3_dose,
        bag_three_volume_ml: 1000.0,
        bag_three_duration_min: 960.0,
        total_dose_mg: total,
        total_duration_hours: 21.0,
        citation: "Prescott LF. BMJ 2:1097, 1979. Modified 3-bag IV protocol. Anaphylactoid reactions most common during Bag 1 (slow rate if flushing/urticaria). Continue NAC beyond 21h if INR > 2 or AST rising."
    }
}

// Acetaminophen toxic dose thresholds
// Goldfrank 11th ed Ch 35
fn apap_toxic_dose(weight_kg: Float) -> String {
    let single_acute = 150.0 * weight_kg
    let concerning = 7500.0
    if single_acute < concerning { return "Single acute toxic dose: 150 mg/kg. For this patient: < 7500 mg. However, ALWAYS use the Rumack-Matthew nomogram with a 4-hour level for single acute ingestions. Chronic supratherapeutic exposure (> 4 g/day in adults) can cause toxicity at lower total doses, especially with alcohol use, fasting, or CYP2E1 induction." }
    return "Single acute toxic dose threshold: 150 mg/kg. For this patient: calculated threshold dose shown. Use Rumack-Matthew nomogram for risk stratification. Risk factors for toxicity at lower doses: chronic alcohol use (CYP2E1 induction + glutathione depletion), fasting/malnutrition (depleted glutathione), isoniazid use (CYP2E1 inducer), Gilbert syndrome."
}

// NAPQI formation pathway
// Key to understanding why acetaminophen is toxic
fn napqi_pathway() -> String {
    return "ACETAMINOPHEN METABOLISM: (i) 90% conjugated by glucuronidation (UGT1A1/1A6) and sulfation (SULT1A1). Produces non-toxic water-soluble metabolites. (ii) 5-10% oxidized by CYP2E1 (minor: CYP1A2, CYP3A4) to NAPQI (N-acetyl-p-benzoquinone imine). (iii) NAPQI normally detoxified by glutathione (GSH) conjugation. (iv) When GSH depleted to < 30% of normal, NAPQI binds covalently to hepatocyte proteins (esp. mitochondrial), triggering centrilobular necrosis. (v) NAC replenishes GSH and provides alternative sulfhydryl substrate."
}


// ==========================================================
// SECTION EIGHT: UTILITY FUNCTIONS
// ==========================================================

// Convert heart rate (bpm) to RR interval (ms)
fn hr_to_rr(heart_rate_bpm: Float) -> Float {
    return 60000.0 / heart_rate_bpm
}

// Body surface area (Mosteller formula) for dose calculations
// BSA = sqrt((height_cm * weight_kg) / 3600)
fn body_surface_area(height_cm: Float, weight_kg: Float) -> Float {
    return sqrt(height_cm * weight_kg / 3600.0)
}

// Anion gap: AG = Na - (Cl + HCO3)
// Normal: 8-12 mEq/L. Elevated in: methanol, uremia, DKA,
// propylene glycol, isoniazid/iron, lactic acidosis,
// ethylene glycol, salicylates (MUDPILES mnemonic)
fn anion_gap(sodium: Float, chloride: Float, bicarbonate: Float) -> Float {
    return sodium - (chloride + bicarbonate)
}

// Osmol gap: measured osmolality - calculated osmolality
// Calculated osmolality = 2*Na + BUN/2.8 + glucose/18 + EtOH/4.6
// Elevated osmol gap (> 10) suggests toxic alcohol ingestion
fn osmol_gap(measured_osm: Float, sodium: Float, bun: Float, glucose: Float, ethanol: Float) -> Float {
    let calc_osm = 2.0 * sodium + bun / 2.8 + glucose / 18.0 + ethanol / 4.6
    return measured_osm - calc_osm
}

// Oxygen saturation gap
// If SpO2 (pulse ox) and SaO2 (ABG co-oximetry) differ significantly,
// consider: CO poisoning (SpO2 falsely normal), methemoglobinemia (SpO2 ~85%)
fn sat_gap(spo2: Float, sao2: Float) -> String {
    let gap = spo2 - sao2
    if abs(gap) < 2.0 { return "No significant saturation gap. Pulse oximetry and co-oximetry agree." }
    if gap > 5.0 { return "POSITIVE SAT GAP (SpO2 > SaO2): Pulse ox falsely elevated. Consider carbon monoxide poisoning (carboxyhemoglobin absorbs light similarly to oxyhemoglobin). Confirm with co-oximetry (COHb level)." }
    if gap < -5.0 { return "NEGATIVE SAT GAP (SpO2 < SaO2): Pulse ox falsely low. Consider methemoglobinemia (SpO2 plateaus at ~85% regardless of true saturation), dyes (methylene blue), or poor perfusion." }
    return "Mild saturation gap. May be clinically insignificant. Correlate with clinical picture."
}

// Lethal dose estimation categories (Hodge-Sterner scale)
// Casarett and Doull's 9th ed Ch 2, Table 2-2.
fn toxicity_rating(ld50_mg_kg: Float) -> String {
    if ld50_mg_kg <= 1.0 { return "EXTREMELY TOXIC (LD50 <= 1 mg/kg). Probable lethal dose for 70 kg adult: < 70 mg (a taste). Examples: botulinum toxin, tetrodotoxin, VX nerve agent, ricin." }
    if ld50_mg_kg <= 50.0 { return "HIGHLY TOXIC (LD50 1-50 mg/kg). Probable lethal dose: 70 mg to 3.5 g. Examples: nicotine, strychnine, cyanide salts, arsenic trioxide, parathion." }
    if ld50_mg_kg <= 500.0 { return "MODERATELY TOXIC (LD50 50-500 mg/kg). Probable lethal dose: 3.5 - 35 g (1 tsp to 1 oz). Examples: phenobarbital, DDT, aspirin, some antihistamines." }
    if ld50_mg_kg <= 5000.0 { return "SLIGHTLY TOXIC (LD50 500-5000 mg/kg). Probable lethal dose: 35 - 350 g (1 oz to 1 pint). Examples: acetaminophen (oral LD50 ~2400 mg/kg in rats), ethanol." }
    return "PRACTICALLY NONTOXIC (LD50 > 5000 mg/kg). Probable lethal dose: > 350 g (> 1 pint). Examples: sucrose, water (at extreme volumes)."
}

// Decontamination decision support
// Goldfrank 11th ed, Ch 8: GI Decontamination.
fn decontamination(hours_since_ingestion: Float, substance_type: String) -> String {
    if hours_since_ingestion > 2.0 {
        if substance_type == "SUSTAINED_RELEASE" { return "Whole bowel irrigation (WBI) with PEG-electrolyte solution may still be effective for sustained-release preparations, drug packets, or lithium/iron. Administer PEG 1-2 L/h (adults) until clear rectal effluent." }
        if substance_type == "PACKET" { return "Whole bowel irrigation recommended for body packers/stuffers. PEG-electrolyte solution until clear effluent. Surgical intervention if obstruction or packet rupture." }
        return "OUTSIDE STANDARD WINDOW: > 2 hours since ingestion. Activated charcoal is generally NOT recommended (most absorption complete by 1-2 hours). Exceptions: agents with slow absorption (anticholinergics), large overdoses (bezoar formation), sustained-release formulations."
    }
    if hours_since_ingestion <= 1.0 { return "WITHIN WINDOW: < 1 hour. Activated charcoal 1 g/kg (max 50 g) PO if airway intact and patient cooperative. NO IPECAC (no longer recommended). Charcoal does NOT bind: iron, lithium, alcohols, cyanide, potassium, heavy metals, hydrocarbons." }
    return "1-2 HOURS: Consider activated charcoal if large ingestion of charcoal-binding substance and intact airway. Effectiveness decreases with time. Risk of aspiration if mental status impaired."
}


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

fn toxicology_function_count() -> Int {
    return 37
}

fn toxicology_struct_count() -> Int {
    return 6
}

fn toxicology_marker_count() -> Int {
    // Hepatotoxicity: 6, Nephrotoxicity: 6, Cardiotoxicity: 5,
    // Neurotoxicity: 4, Hematotoxicity: 5 = 26 total markers
    return 26
}

fn toxicology_toxidrome_count() -> Int {
    return 7
}

fn toxicology_antidote_count() -> Int {
    return 13
}

fn toxicology_qt_drug_count() -> Int {
    return 10
}
