import { GraphEdge } from './graph.js';

/**
 * Graph edge confidence + reinforcement primitives (issue #681, PR 1/3).
 *
 * Pure functions only — no I/O, no global state. The maintenance job (PR 2/3)
 * and PageRank weighting (PR 3/3) compose these helpers.
 *
 * Schema:
 *   - `confidence`   ∈ [0, 1]; missing on legacy edges, treated as 1.0.
 *   - `lastReinforcedAt` — ISO timestamp of most recent reinforcement; missing
 *     on legacy edges, treated as the original edge `ts`.
 *
 * Defaults documented here are the agreed-on starting points and may be
 * tuned later via config. They live as named constants so call sites and
 * tests share the same values.
 */

/** Default confidence bump per reinforcement event. */
declare const DEFAULT_REINFORCE_DELTA = 0.05;
/** Maximum edge confidence — confidence is capped at this on reinforcement. */
declare const CONFIDENCE_CEILING = 1;
/** Default decay window in milliseconds (90 days). */
declare const DEFAULT_DECAY_WINDOW_MS: number;
/** Default decay floor — confidence will not drop below this purely from age. */
declare const DEFAULT_DECAY_FLOOR = 0.1;
/** Default per-window decay amount (linear). */
declare const DEFAULT_DECAY_PER_WINDOW = 0.1;
/**
 * Treat a missing `confidence` on a legacy edge as 1.0.
 * Clamps to `[0, CONFIDENCE_CEILING]` so downstream math is well-behaved.
 */
declare function readEdgeConfidence(edge: Pick<GraphEdge, "confidence">): number;
/**
 * Resolve the reference timestamp for decay calculations.
 * Falls back to the edge's creation `ts` when `lastReinforcedAt` is absent
 * (legacy edges have never been reinforced).
 */
declare function readLastReinforcedAt(edge: Pick<GraphEdge, "lastReinforcedAt" | "ts">): string;
/**
 * Reinforce an edge: bump confidence by `delta` (capped at 1.0) and stamp
 * `lastReinforcedAt = now`. Pure — returns a new edge, never mutates input.
 *
 * Idempotency note: calling reinforceEdge twice with the same `now` and a
 * delta of 0 returns an edge equal to the input (modulo timestamp).
 *
 * @param edge  the edge to reinforce
 * @param now   ISO timestamp of the reinforcement event
 * @param delta confidence bump; defaults to DEFAULT_REINFORCE_DELTA
 */
declare function reinforceEdge(edge: GraphEdge, now: string, delta?: number): GraphEdge;
/** Options for {@link decayEdgeConfidence}. */
interface DecayOptions {
    /** Decay window in milliseconds. Defaults to 90 days. */
    windowMs?: number;
    /** Per-window decay amount. Defaults to 0.1. */
    perWindow?: number;
    /** Floor confidence will not decay below. Defaults to 0.1. */
    floor?: number;
}
/**
 * Apply linear decay to an edge's confidence based on time since last
 * reinforcement (or creation, for legacy edges). Pure — returns a new edge.
 *
 * Decay model:
 *   age = now - lastReinforcedAt
 *   if age <= windowMs:           confidence unchanged
 *   else:                          confidence -= perWindow * floor((age - windowMs) / windowMs + 1)
 *   confidence is clamped to [floor, 1.0]
 *
 * Boundary semantics: `age === windowMs` is INSIDE the no-decay grace period
 * (`<=`). Decay only kicks in once age strictly exceeds the window. This
 * keeps the boundary deterministic and easy to test.
 *
 * @param edge edge to decay (confidence and lastReinforcedAt may be absent)
 * @param now  ISO timestamp representing "now"
 * @param opts override window / per-window / floor; otherwise defaults are used
 */
declare function decayEdgeConfidence(edge: GraphEdge, now: string, opts?: DecayOptions): GraphEdge;

export { CONFIDENCE_CEILING, DEFAULT_DECAY_FLOOR, DEFAULT_DECAY_PER_WINDOW, DEFAULT_DECAY_WINDOW_MS, DEFAULT_REINFORCE_DELTA, type DecayOptions, decayEdgeConfidence, readEdgeConfidence, readLastReinforcedAt, reinforceEdge };
