"""
Per-org incremental-sync timestamp tracking, backed by Redis.

There is no server-side "last incremental sync" timestamp in the DB (the
SyncHistory table only tracks historical backfills). We keep a lightweight
last-sync marker in Redis so the post-send hook can decide whether a fresh
sync is worth enqueuing, without a schema migration.

Keys: ``last_sync:{org_id}`` → unix epoch seconds (float, as string).
Redis is already the Celery broker / rate-limit store.
"""

from __future__ import annotations

import logging
import os
import time
from typing import Optional

logger = logging.getLogger(__name__)

REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379/0")

_redis = None


def _client():
    """Lazily build a module-wide Redis client; return None if unavailable."""
    global _redis
    if _redis is None:
        try:
            import redis  # redis-py, already a dependency (Celery broker)

            _redis = redis.Redis.from_url(REDIS_URL)
        except Exception as exc:  # pragma: no cover - defensive
            logger.warning("sync_state: Redis unavailable (%s); last-sync disabled", exc)
            _redis = False  # sentinel: tried and failed
    return _redis or None


def set_last_sync(org_id: int, when: Optional[float] = None) -> None:
    """Record that org_id was just synced (epoch seconds; defaults to now)."""
    client = _client()
    if not client:
        return
    try:
        client.set(f"last_sync:{org_id}", when if when is not None else time.time())
    except Exception as exc:  # pragma: no cover - defensive
        logger.debug("sync_state.set_last_sync failed: %s", exc)


def get_last_sync(org_id: int) -> Optional[float]:
    """Return the epoch-seconds of org_id's last sync, or None if unknown."""
    client = _client()
    if not client:
        return None
    try:
        raw = client.get(f"last_sync:{org_id}")
        return float(raw) if raw is not None else None
    except Exception as exc:  # pragma: no cover - defensive
        logger.debug("sync_state.get_last_sync failed: %s", exc)
        return None


def seconds_since_last_sync(org_id: int) -> Optional[float]:
    """Seconds since org_id's last sync, or None if never recorded."""
    last = get_last_sync(org_id)
    return (time.time() - last) if last is not None else None
