import base64
import json

import aiohttp
from cryptography.hazmat.primitives import serialization

from snek.system.view import BaseFormView


class PushView(BaseFormView):
    async def get(self):
        return await self.json_response(
            {
                "publicKey": base64.b64encode(
                    self.app.services.push.public_key.public_bytes(
                        encoding=serialization.Encoding.X962,
                        format=serialization.PublicFormat.UncompressedPoint,
                    )
                )
                .decode("utf-8")
                .rstrip("="),
            }
        )

    async def post(self):
        user_id = self.session.get("uid")
        if user_id:
            user = await self.app.services.user.get(uid=user_id)
            if not user:
                return await self.json_response({"error": "User not found"}, status=404)

            body = await self.request.json()

            if not all(
                [
                    "endpoint" in body,
                    "keys" in body,
                    "p256dh" in body["keys"],
                    "auth" in body["keys"],
                ]
            ):
                return await self.json_response(
                    {"error": "Invalid request"}, status=400
                )

            regist = await self.app.services.push.register(
                user_uid=user_id,
                endpoint=body["endpoint"],
                key_auth=body["keys"]["auth"],
                key_p256dh=body["keys"]["p256dh"],
            )

            if regist:
                test_payload = {
                    "title": f"Welcome {user['nick']}!",
                    "message": "You'll now receive notifications from Snek :D",
                    "icon": "/image/snek192.png",
                    "url": "/web.html",
                }

                notification_info = (
                    self.app.services.push.create_notification_info_with_payload(
                        body["endpoint"],
                        body["keys"]["auth"],
                        body["keys"]["p256dh"],
                        json.dumps(test_payload),
                    )
                )

                headers = {
                    **notification_info["headers"],
                    "TTL": "60",
                }

                async with aiohttp.ClientSession() as session:
                    async with session.post(
                        body["endpoint"],
                        headers=headers,
                        data=notification_info["data"],
                    ) as post_notification:
                        print(post_notification.status)
                        print(post_notification.text)
                        print(post_notification.headers)

        return await self.json_response({"registered": True})
