"""Storage for web-push subscriptions (postgres, asyncpg)."""

from __future__ import annotations

import uuid
from dataclasses import dataclass


@dataclass
class PushSubscription:
    id: str
    user_id: str
    endpoint: str
    p256dh: str
    auth: str
    user_agent: str | None = None


_UPSERT = """
INSERT INTO push_subscriptions (id, user_id, endpoint, p256dh, auth, user_agent)
VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT (endpoint) DO UPDATE
SET user_id = EXCLUDED.user_id,
    p256dh = EXCLUDED.p256dh,
    auth = EXCLUDED.auth,
    user_agent = EXCLUDED.user_agent
RETURNING id
"""

_SELECT_FOR_USER = """
SELECT id, user_id, endpoint, p256dh, auth, user_agent
FROM push_subscriptions WHERE user_id = $1
"""

_DELETE = "DELETE FROM push_subscriptions WHERE endpoint = $1"

_MARK_PUSHED = "UPDATE push_subscriptions SET last_push_at = now() WHERE id = $1"


class PushSubscriptionStore:
    def __init__(self, pool):
        self._pool = pool

    async def upsert(
        self,
        user_id: str,
        endpoint: str,
        p256dh: str,
        auth: str,
        user_agent: str | None = None,
    ) -> PushSubscription:
        sub_id = await self._pool.fetchval(
            _UPSERT, str(uuid.uuid4()), user_id, endpoint, p256dh, auth, user_agent
        )
        return PushSubscription(
            id=sub_id, user_id=user_id, endpoint=endpoint, p256dh=p256dh,
            auth=auth, user_agent=user_agent,
        )

    async def delete(self, endpoint: str) -> None:
        await self._pool.execute(_DELETE, endpoint)

    async def list_for_user(self, user_id: str) -> list[PushSubscription]:
        rows = await self._pool.fetch(_SELECT_FOR_USER, user_id)
        return [
            PushSubscription(
                id=r["id"], user_id=r["user_id"], endpoint=r["endpoint"],
                p256dh=r["p256dh"], auth=r["auth"], user_agent=r["user_agent"],
            )
            for r in rows
        ]

    async def mark_pushed(self, subscription_id: str) -> None:
        await self._pool.execute(_MARK_PUSHED, subscription_id)