"""STI/LTI decay and propagation."""
from __future__ import annotations


def decay_sti(sti: float, decay_rate: float) -> float:
    """Apply multiplicative decay to short-term importance."""
    return sti * (1.0 - decay_rate)


def promote_lti(sti: float, lti: float, threshold: float) -> float:
    """Promote STI to LTI when STI exceeds threshold."""
    if sti > threshold:
        return max(lti, sti * 0.5)
    return lti


def propagate_sti(
    atom_id: str, boost: float, propagation_factor: float, db, tenant_id: str, space: str
) -> None:
    """Spread a fraction of STI to 1-hop neighbors within the same space.

    Single-hop only — no recursion, no oscillation risk.
    """
    spread = boost * propagation_factor
    if spread < 0.01:
        return

    # Relation atoms store their endpoints in source_id/target_id columns —
    # the standard forward/backward query finds nothing for them.
    row = db.fetchone("SELECT type, source_id, target_id FROM atoms WHERE id = ?", (atom_id,))
    if row and row["type"] == "relation":
        neighbor_ids = [x for x in (row["source_id"], row["target_id"]) if x]
    else:
        forward = db.fetchall(
            "SELECT target_id FROM atoms WHERE source_id = ? AND type = 'relation' AND tenant_id = ? AND space = ?",
            (atom_id, tenant_id, space),
        )
        backward = db.fetchall(
            "SELECT source_id FROM atoms WHERE target_id = ? AND type = 'relation' AND tenant_id = ? AND space = ?",
            (atom_id, tenant_id, space),
        )
        neighbor_ids = [r["target_id"] for r in forward if r["target_id"]]
        neighbor_ids += [r["source_id"] for r in backward if r["source_id"]]

    for nid in neighbor_ids:
        db.execute(
            "UPDATE atoms SET sti = MIN(sti + ?, 3.0) WHERE id = ? AND tenant_id = ? AND space = ?",
            (spread, nid, tenant_id, space),
        )
