"""
Thin MongoDB read/write layer for the afs_shares collection.

Uses SHARE_MONGO_URI (production MongoDB) — not MONGODB_LOCAL_URI.
This is intentional: share URLs resolve at rezend.ai, which reads from the same
production MongoDB. The MCP tool is self-contained and runs on any machine;
SHARE_MONGO_URI is what makes shares publicly accessible.

Graceful degradation: if SHARE_MONGO_URI is unset or MongoDB is unreachable,
store_share returns the share_id anyway (UUID assigned in-process) so the
caller can still return a URL. The document simply won't be persisted.

Usage:
    from afs.store.share_store import store_share, get_share

    share_id = store_share({
        "question": "Which database should we use?",
        "strategies": [...],
        "ablation_id": "uuid | None",
        "sensitivity": {"stability_score": 82, ...} | None,
        "expires_at": datetime(...),
    })

    doc = get_share(share_id)   # returns full record or None
"""

import os
import logging
import uuid
from datetime import datetime, timezone
from typing import Optional

logger = logging.getLogger(__name__)

# Module-level connection state. Initialized lazily on first call.
# _reset() clears these for test isolation.
_client = None
_collection = None
_unavailable = False   # once we know DB is unreachable, skip further attempts
_ttl_ensured = False   # TTL index created at most once per process


def _get_collection():
    """Return the afs_shares Collection, or None if MongoDB is unavailable.

    Connects once per process lifetime. Subsequent calls reuse the cached
    collection. Once connection fails, _unavailable is set and no further
    attempts are made within this process.
    """
    global _client, _collection, _unavailable, _ttl_ensured

    if _unavailable:
        return None

    if _collection is not None:
        return _collection

    uri = os.environ.get("SHARE_MONGO_URI")
    if not uri:
        logger.warning(
            "[share_store] SHARE_MONGO_URI not set — shares will not be persisted"
        )
        _unavailable = True
        return None

    try:
        from pymongo import MongoClient, ASCENDING

        _client = MongoClient(uri, serverSelectionTimeoutMS=3000)
        _client.admin.command("ping")   # fast connectivity check — raises on failure

        db = _client.get_default_database()
        _collection = db["afs_shares"]

        # TTL index: MongoDB auto-deletes documents when expires_at is reached.
        # expireAfterSeconds=0 means delete at the expires_at datetime itself.
        if not _ttl_ensured:
            _collection.create_index(
                [("expires_at", ASCENDING)],
                expireAfterSeconds=0,
                name="ttl_expires_at",
                background=True,
            )
            _ttl_ensured = True

        logger.info(
            "[share_store] Connected — using %s.afs_shares", db.name
        )
        return _collection

    except ImportError:
        logger.warning(
            "[share_store] pymongo not installed — shares will not be persisted. "
            "Install with: pip install pymongo"
        )
        _unavailable = True
        return None

    except Exception as exc:
        logger.warning(
            "[share_store] MongoDB unavailable (%s) — shares will not be persisted",
            exc,
        )
        _unavailable = True
        return None


def store_share(record: dict) -> str:
    """Persist a share record to afs_shares.

    Assigns a fresh UUID share_id if the record doesn't already have one.
    Adds created_at timestamp. Returns the share_id whether or not
    persistence succeeded.

    Args:
        record: Dict containing at minimum:
            - question (str)
            - strategies (list)
            - expires_at (datetime, timezone-aware)
            Optional: ablation_id, sensitivity, metadata.
            Must not contain an _id field — MongoDB assigns one.

    Returns:
        share_id (str): UUID identifying this share.
    """
    share_id = record.get("share_id") or str(uuid.uuid4())

    doc = {
        **record,
        "share_id": share_id,
        "created_at": datetime.now(timezone.utc),
        "view_count": record.get("view_count", 0),
    }
    doc.pop("_id", None)

    col = _get_collection()
    if col is not None:
        try:
            col.insert_one(doc)
        except Exception as exc:
            logger.warning(
                "[share_store] Failed to insert share %s: %s", share_id, exc
            )

    return share_id


def get_share(share_id: str) -> Optional[dict]:
    """Retrieve a share record by share_id.

    Returns:
        The stored document (without _id) or None if not found / DB unavailable.
    """
    col = _get_collection()
    if col is None:
        return None
    try:
        return col.find_one({"share_id": share_id}, {"_id": 0})
    except Exception as exc:
        logger.warning(
            "[share_store] Failed to retrieve share %s: %s", share_id, exc
        )
        return None


def _reset() -> None:
    """Reset connection state. Call between tests that manipulate env vars or mock _get_collection."""
    global _client, _collection, _unavailable, _ttl_ensured
    if _client is not None:
        try:
            _client.close()
        except Exception:
            pass
    _client = None
    _collection = None
    _unavailable = False
    _ttl_ensured = False
