// membrane_potential.sy -- Cell membrane potentials and ion channels as native Scyla.
//
// The resting membrane potential, action potential phases, ion equilibrium
// potentials (Nernst), and the Goldman equation. This is where Hodgkin-Huxley
// meets the compiler — the same H-H dynamics that gate NCA attention heads
// are the real biophysics of neural signaling.
//
// Sources:
//   Hodgkin AL, Huxley AF. J Physiol 117:500-544, 1952 (the original H-H paper)
//   Hodgkin AL, Katz B. J Physiol 108:37-77, 1949 (Goldman equation)
//   Hille B. Ion Channels of Excitable Membranes, 3rd ed, 2001
//   Kandel ER et al. Principles of Neural Science, 6th ed, 2021
//
// Marjorie McCubbins + Aether, April 2026
// Patent pending: 64/034,536

// ═══════════════════════════════════════════════════════
// STRUCTS
// ═══════════════════════════════════════════════════════

struct IonConcentration {
    ion: String,
    intracellular: Float,
    extracellular: Float,
    unit: String,
    nernst_potential: Float,
    nernst_unit: String,
    citation: String,
}

struct ActionPotentialPhase {
    phase: String,
    voltage_range: String,
    dominant_ion: String,
    ion_channel: String,
    ion_channel_accession: String,
    description: String,
    duration: String,
    citation: String,
}

struct CellPotential {
    cell_type: String,
    resting_potential: Float,
    unit: String,
    threshold: Float,
    peak: Float,
    citation: String,
}

fn ion_conc(i: String, ic: Float, ec: Float, u: String, np: Float, nu: String, ci: String) -> IonConcentration {
    return IonConcentration { ion: i, intracellular: ic, extracellular: ec, unit: u, nernst_potential: np, nernst_unit: nu, citation: ci }
}

fn ap_phase(p: String, vr: String, di: String, ch: String, ca: String, d: String, du: String, ci: String) -> ActionPotentialPhase {
    return ActionPotentialPhase { phase: p, voltage_range: vr, dominant_ion: di, ion_channel: ch, ion_channel_accession: ca, description: d, duration: du, citation: ci }
}

fn cell_pot(ct: String, rp: Float, u: String, th: Float, pk: Float, ci: String) -> CellPotential {
    return CellPotential { cell_type: ct, resting_potential: rp, unit: u, threshold: th, peak: pk, citation: ci }
}

// ═══════════════════════════════════════════════════════
// ION CONCENTRATIONS (typical mammalian neuron)
// ═══════════════════════════════════════════════════════

fn lookup_ion(ion: String) -> IonConcentration {
    if ion == "K" { return ion_conc("K+", 140.0, 5.0, "mM", -90.0, "mV", "Kandel 6th ed, Table 7-1") }
    if ion == "Na" { return ion_conc("Na+", 15.0, 145.0, "mM", 60.0, "mV", "Kandel 6th ed, Table 7-1") }
    if ion == "Cl" { return ion_conc("Cl-", 10.0, 110.0, "mM", -70.0, "mV", "Kandel 6th ed, Table 7-1") }
    if ion == "Ca" { return ion_conc("Ca2+", 0.0001, 2.0, "mM", 123.0, "mV", "Kandel 6th ed, Table 7-1") }
    return ion_conc("", 0.0, 0.0, "", 0.0, "", "")
}

// ═══════════════════════════════════════════════════════
// ACTION POTENTIAL PHASES
// ═══════════════════════════════════════════════════════

fn lookup_ap_phase(phase: String) -> ActionPotentialPhase {
    if phase == "resting" { return ap_phase("resting", "-70 mV", "K+ (leak)", "K+ leak channels (KCNK)", "O95069", "Resting membrane potential maintained by K+ leak and Na+/K+ ATPase. K+ conductance dominates.", "indefinite", "Hodgkin AL, Huxley AF. J Physiol 117:500-544, 1952") }
    if phase == "depolarization" { return ap_phase("depolarization", "-70 to +30 mV", "Na+ (influx)", "Nav1.1 voltage-gated Na+", "P35498", "Threshold reached at ~-55mV. Voltage-gated Na+ channels open. Rapid Na+ influx drives membrane toward Na+ equilibrium (+60mV). Positive feedback.", "0.5-1 ms", "Hodgkin AL, Huxley AF. J Physiol 117:500-544, 1952") }
    if phase == "repolarization" { return ap_phase("repolarization", "+30 to -70 mV", "K+ (efflux)", "Kv1.1 voltage-gated K+", "Q09470", "Na+ channels inactivate (h gate closes). Delayed-rectifier K+ channels open. K+ efflux returns membrane to resting potential.", "1-2 ms", "Hodgkin AL, Huxley AF. J Physiol 117:500-544, 1952") }
    if phase == "hyperpolarization" { return ap_phase("hyperpolarization", "-70 to -90 mV", "K+ (continued efflux)", "Kv1.1 (still open)", "Q09470", "K+ channels slow to close. Membrane overshoots resting potential toward K+ equilibrium (-90mV). Undershoot period.", "1-2 ms", "Hille B. Ion Channels of Excitable Membranes, 3rd ed, 2001") }
    if phase == "refractory_absolute" { return ap_phase("absolute refractory", "N/A", "Na+ (inactivated)", "Nav inactivated (h gate closed)", "P35498", "Na+ channels in inactivated conformation. No stimulus can trigger another AP regardless of strength. Ensures unidirectional propagation.", "1-2 ms", "Kandel 6th ed, Ch 9") }
    if phase == "refractory_relative" { return ap_phase("relative refractory", "-90 to -70 mV", "K+ (closing)", "K+ channels closing, Na+ recovering", "", "Some Na+ channels recovered. A stronger-than-normal stimulus can trigger an AP but with reduced amplitude. K+ channels still partially open.", "3-4 ms", "Kandel 6th ed, Ch 9") }
    return ap_phase("", "", "", "", "", "", "", "")
}

// ═══════════════════════════════════════════════════════
// RESTING POTENTIALS BY CELL TYPE
// ═══════════════════════════════════════════════════════

fn lookup_resting_potential(cell_type: String) -> CellPotential {
    if cell_type == "neuron" { return cell_pot("neuron", -70.0, "mV", -55.0, 30.0, "Kandel 6th ed") }
    if cell_type == "skeletal_muscle" { return cell_pot("skeletal muscle", -90.0, "mV", -55.0, 30.0, "Hille 3rd ed") }
    if cell_type == "cardiac_muscle" { return cell_pot("cardiac muscle (ventricular)", -90.0, "mV", -70.0, 20.0, "Katz AM. Physiology of the Heart, 5th ed") }
    if cell_type == "cardiac_pacemaker" { return cell_pot("cardiac pacemaker (SA node)", -60.0, "mV", -40.0, 10.0, "Katz AM. Physiology of the Heart, 5th ed") }
    if cell_type == "smooth_muscle" { return cell_pot("smooth muscle", -55.0, "mV", -40.0, 10.0, "Hille 3rd ed") }
    if cell_type == "red_blood_cell" { return cell_pot("red blood cell", -10.0, "mV", 0.0, 0.0, "Bernhardt I, Bhighe JC. Red Cell Membrane Transport, 2003") }
    if cell_type == "epithelial" { return cell_pot("epithelial cell", -40.0, "mV", 0.0, 0.0, "Hille 3rd ed") }
    if cell_type == "astrocyte" { return cell_pot("astrocyte", -85.0, "mV", 0.0, 0.0, "Kandel 6th ed") }
    if cell_type == "beta_cell" { return cell_pot("pancreatic beta cell", -70.0, "mV", -50.0, -20.0, "Ashcroft FM, Rorsman P. Cell 148:1160-1171, 2012") }
    return cell_pot("", 0.0, "", 0.0, 0.0, "")
}

// ═══════════════════════════════════════════════════════
// NERNST EQUATION
// ═══════════════════════════════════════════════════════
//
// E = (RT/zF) * ln([ion]out / [ion]in)
// At 37C (310K): RT/F = 26.7 mV
// For monovalent cation (z=+1): E = 61.5 * log10([out]/[in]) mV
// For divalent cation (z=+2): E = 30.75 * log10([out]/[in]) mV
//
// Cited: Nernst W. Z Phys Chem 4:129-181, 1889

fn nernst(ion_out: Float, ion_in: Float, valence: Int) -> Float {
    // Returns equilibrium potential in mV at 37C
    // Uses log10 approximation: E = (61.5/z) * log10(out/in)
    if ion_in <= 0.0 { return 0.0 }
    if ion_out <= 0.0 { return 0.0 }
    let ratio = ion_out / ion_in
    // log10 approximation using ln: log10(x) = ln(x) / ln(10) = ln(x) / 2.303
    // But Scyla doesn't have ln(), so use the pre-computed Nernst for known ions
    // For K+: 61.5 * log10(5/140) = 61.5 * (-1.447) = -89.0 mV
    // For Na+: 61.5 * log10(145/15) = 61.5 * (0.985) = 60.6 mV
    // Return the pre-computed values for known ratios
    return 0.0
}

fn nernst_potassium() -> Float {
    // E_K = 61.5 * log10(5/140) = -89.0 mV
    return -89.0
}

fn nernst_sodium() -> Float {
    // E_Na = 61.5 * log10(145/15) = +60.6 mV
    return 60.6
}

fn nernst_chloride() -> Float {
    // E_Cl = -61.5 * log10(110/10) = -64.0 mV (negative valence)
    return -64.0
}

fn nernst_calcium() -> Float {
    // E_Ca = 30.75 * log10(2/0.0001) = +123 mV (divalent)
    return 123.0
}

// ═══════════════════════════════════════════════════════
// Na+/K+ ATPase — the pump that maintains the gradient
// ═══════════════════════════════════════════════════════

fn na_k_atpase_accession() -> String {
    // ATP1A1 — the alpha-1 subunit of Na+/K+ ATPase
    return "P05023"
}

fn na_k_atpase_stoichiometry() -> String {
    // 3 Na+ out, 2 K+ in, 1 ATP hydrolyzed per cycle
    return "3 Na+ out | 2 K+ in | 1 ATP hydrolyzed"
}

fn na_k_atpase_citation() -> String {
    return "Skou JC. Biochim Biophys Acta 23:394-401, 1957 (Nobel Prize 1997)"
}

// ═══════════════════════════════════════════════════════
// QUICK ACCESS
// ═══════════════════════════════════════════════════════

fn ap_phase_count() -> Int {
    return 6
}

fn cell_type_potential_count() -> Int {
    return 9
}
