# retoor <retoor@molodetz.nl>

import logging
from datetime import datetime, timedelta, timezone

from devplacepy.database import get_int_setting
from devplacepy.push import providers, store
from devplacepy.push.delivery import (
    DEFAULT_TIMEOUT_SECONDS,
    MAX_TIMEOUT_SECONDS,
    MIN_TIMEOUT_SECONDS,
    TIMEOUT_KEY,
)
from devplacepy.services.base import BaseService, ConfigField

logger = logging.getLogger(__name__)

RETENTION_KEY = "push_dead_retention_days"
DEFAULT_RETENTION_DAYS = 30


class PushService(BaseService):
    title = "Push notifications"
    description = (
        "Configures the push providers and prunes dead subscriptions. Delivery is "
        "independent of this service and continues while it is stopped."
    )
    details = (
        "Notifications reach a user through every provider they have a live subscription "
        "for. A provider delivers only while its own Enabled toggle is on and its "
        "configuration is complete, so an unconfigured provider is inert."
    )
    default_enabled = True
    min_interval = 3600
    METRICS_SECONDS = 300
    config_fields = [
        ConfigField(
            RETENTION_KEY,
            "Dead subscription retention (days)",
            type="int",
            default=DEFAULT_RETENTION_DAYS,
            minimum=0,
            help="Subscriptions the push services rejected as gone are removed after this many days. 0 disables pruning.",
            group="General",
        ),
        ConfigField(
            TIMEOUT_KEY,
            "Delivery timeout (seconds)",
            type="int",
            default=DEFAULT_TIMEOUT_SECONDS,
            minimum=MIN_TIMEOUT_SECONDS,
            maximum=MAX_TIMEOUT_SECONDS,
            help="Per request timeout used for every push provider.",
            group="General",
        ),
        *providers.admin_fields(),
    ]

    def __init__(self) -> None:
        super().__init__("push", interval_seconds=86400)

    async def run_once(self) -> None:
        days = get_int_setting(RETENTION_KEY, DEFAULT_RETENTION_DAYS)
        if days <= 0:
            self.log("Retention disabled (0 days); nothing pruned")
            return
        cutoff = (datetime.now(timezone.utc) - timedelta(days=days)).isoformat()
        removed = store.prune(cutoff)
        self.log(f"Pruned {removed} dead push subscriptions older than {days}d")

    def collect_metrics(self) -> dict:
        totals = store.counts()
        metrics = {"dead": totals.get("dead", 0)}
        for provider in providers.PROVIDERS.values():
            metrics[f"{provider.name}_active"] = totals.get(provider.name, 0)
            metrics[f"{provider.name}_ready"] = (
                1 if providers.is_active(provider) else 0
            )
        return metrics
