# retoor <retoor@molodetz.nl>

import logging
from datetime import datetime, timezone
from typing import Any

from devplacepy.database import db, get_table
from devplacepy.push.providers import DEFAULT_PROVIDER
from devplacepy.utils import generate_uid

logger = logging.getLogger(__name__)

TABLE = "push_registration"


def table():
    return get_table(TABLE)


def provider_of(registration: dict[str, Any]) -> str:
    return registration.get("provider") or DEFAULT_PROVIDER


def active_for_user(user_uid: str) -> list[dict[str, Any]]:
    return list(table().find(user_uid=user_uid, deleted_at=None))


def register(
    user_uid: str, provider: str, fields: dict[str, Any]
) -> tuple[dict[str, Any], bool]:
    registrations = table()
    existing = registrations.find_one(
        user_uid=user_uid, provider=provider, deleted_at=None, **fields
    )
    if existing:
        logger.debug("Push subscription already registered for user %s", user_uid)
        return existing, False

    record = {
        "uid": generate_uid(),
        "user_uid": user_uid,
        "provider": provider,
        "created_at": datetime.now(timezone.utc).isoformat(),
        "deleted_at": None,
        **fields,
    }
    registrations.insert(record)
    logger.info("Registered %s push subscription for user %s", provider, user_uid)
    return record, True


def mark_dead(registration_id: int) -> None:
    table().update(
        {"id": registration_id, "deleted_at": datetime.now(timezone.utc).isoformat()},
        ["id"],
    )
    logger.info("Soft-deleted dead push subscription id=%s", registration_id)


def prune(cutoff: str) -> int:
    if TABLE not in db.tables:
        return 0
    rows = list(table().find(deleted_at={"<": cutoff}))
    if not rows:
        return 0
    table().delete(deleted_at={"<": cutoff})
    return len(rows)


def counts() -> dict[str, int]:
    if TABLE not in db.tables:
        return {}
    totals: dict[str, int] = {"dead": 0}
    for row in db.query(
        f"SELECT provider AS provider, deleted_at IS NULL AS live, COUNT(*) AS total "
        f"FROM {TABLE} GROUP BY provider, deleted_at IS NULL"
    ):
        provider = row["provider"] or DEFAULT_PROVIDER
        if row["live"]:
            totals[provider] = totals.get(provider, 0) + int(row["total"])
        else:
            totals["dead"] += int(row["total"])
    return totals
