"""offer_tick — auto-expiration for offers past expires_timestamp.

Idempotent: running twice on an already-expired offer is a no-op.
"""

from ..models.offer import (
    MpsOffer,
    OFFER_STATE_PENDING,
    OFFER_STATE_COUNTERED,
    now_timestamp,
)
from .offer import expire_offer


def tick(dbsession, now_ms=None):
    """Expire any non-terminal offer past expires_timestamp.
    Returns a dict {expired: int}. Caller manages its txn boundary.
    """
    if now_ms is None:
        now_ms = now_timestamp()

    candidates = (
        dbsession.query(MpsOffer)
        .filter(MpsOffer.state.in_([OFFER_STATE_PENDING, OFFER_STATE_COUNTERED]))
        .filter(MpsOffer.expires_timestamp <= now_ms)
        .all()
    )
    expired = 0
    for offer in candidates:
        expire_offer(offer, now_ms=now_ms)
        expired += 1
    return {"expired": expired}
