# retoor <retoor@molodetz.nl>

from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Any

import httpx

from devplacepy.database import get_setting
from devplacepy.services.base import ConfigField

ACCEPTED = "accepted"
DEAD = "dead"
REJECTED = "rejected"


@dataclass(frozen=True)
class Delivery:
    status: str
    detail: str = ""
    dead_before: str | None = None


class PushProvider(ABC):
    name = ""
    label = ""
    config_fields: list[ConfigField] = []

    @property
    def enabled_key(self) -> str:
        return f"push_{self.name}_enabled"

    def enabled_field(self) -> ConfigField:
        return ConfigField(
            self.enabled_key,
            "Enabled",
            type="bool",
            default=True,
            help=f"Deliver notifications through {self.label}.",
            group=self.label,
        )

    def all_fields(self) -> list[ConfigField]:
        return [self.enabled_field(), *self.config_fields]

    def is_enabled(self) -> bool:
        return get_setting(self.enabled_key, "1") == "1"

    def is_active(self) -> bool:
        return self.is_enabled() and self.is_configured()

    def client_config(self) -> dict[str, Any]:
        return {}

    def stamp_registration(self, fields: dict[str, Any]) -> dict[str, Any]:
        return fields

    def delivery_client(self, timeout: float) -> httpx.AsyncClient:
        from devplacepy import stealth

        return stealth.stealth_async_client(timeout=timeout)

    def closes_delivery_client(self) -> bool:
        return True

    async def aclose(self) -> None:
        return None

    @abstractmethod
    def is_configured(self) -> bool: ...

    @abstractmethod
    def parse_registration(self, body: dict[str, Any]) -> dict[str, Any] | None: ...

    @abstractmethod
    def prepare(self, payload: dict[str, Any]) -> str: ...

    @abstractmethod
    async def deliver(
        self, client: httpx.AsyncClient, registration: dict[str, Any], prepared: str
    ) -> Delivery: ...
