"""
Deployment utilities for Mothership bots
"""
import os
import json
from typing import Optional, Callable, Awaitable, Any, Dict
from aiohttp import web
from telegram import Update
from .bot_factory import BotInstance
from .types import DeploymentConfig


class Deployer:
    """Bot deployment utilities"""

    @staticmethod
    async def start_local(
        instance: BotInstance,
        config: Optional[DeploymentConfig] = None
    ) -> web.Application:
        """
        Start bot in local development mode (polling)

        Args:
            instance: Bot instance
            config: Optional deployment configuration

        Returns:
            aiohttp web application (for health checks)
        """
        config = config or {}
        port = config.get("port", 3000)

        # Start bot
        await instance.start()

        # Start polling
        instance.logger.info(f"Starting polling on port {port}...")
        await instance.app.updater.start_polling()

        # Create health check server
        app = web.Application()

        async def health_check(request: web.Request) -> web.Response:
            return web.Response(text="OK")

        app.router.add_get("/", health_check)
        app.router.add_get("/health", health_check)

        # Start server
        runner = web.AppRunner(app)
        await runner.setup()
        site = web.TCPSite(runner, "0.0.0.0", port)
        await site.start()

        instance.logger.success(f"Bot running on http://localhost:{port}")

        return app

    @staticmethod
    def create_serverless_handler(
        instance: BotInstance,
        webhook_secret: Optional[str] = None
    ) -> Callable[[web.Request], Awaitable[web.Response]]:
        """
        Create serverless handler for webhooks (Vercel, Netlify, etc.)

        Args:
            instance: Bot instance
            webhook_secret: Optional webhook secret for verification

        Returns:
            Request handler function
        """
        secret = webhook_secret or os.getenv("WEBHOOK_SECRET")

        async def handler(request: web.Request) -> web.Response:
            # Health check endpoints
            if request.method == "GET":
                if request.path in ["/", "/health", "/api/webhook"]:
                    return web.Response(
                        text=json.dumps({
                            "status": "ok",
                            "bot": instance.bot_name
                        }),
                        content_type="application/json"
                    )

            # Webhook endpoint
            if request.method == "POST":
                # Verify webhook secret if configured
                if secret:
                    request_secret = request.headers.get("x-telegram-bot-api-secret-token")
                    if request_secret != secret:
                        instance.logger.warn("Webhook secret mismatch")
                        return web.Response(status=403, text="Forbidden")

                # Parse update
                try:
                    body = await request.json()
                    update = Update.de_json(body, instance.app.bot)

                    # Process update
                    await instance.app.process_update(update)

                    return web.Response(text="OK")

                except Exception as e:
                    instance.logger.error("Error processing webhook", e)
                    return web.Response(status=500, text="Internal Server Error")

            return web.Response(status=404, text="Not Found")

        return handler

    @staticmethod
    async def setup_webhook(
        instance: BotInstance,
        config: DeploymentConfig
    ) -> None:
        """
        Setup webhook with Telegram

        Args:
            instance: Bot instance
            config: Deployment configuration with webhook_url

        Raises:
            ValueError: If webhook_url not provided or not HTTPS
        """
        webhook_url = config.get("webhook_url")
        if not webhook_url:
            raise ValueError("webhook_url is required for webhook setup")

        if not webhook_url.startswith("https://"):
            raise ValueError("webhook_url must be HTTPS")

        webhook_secret = config.get("webhook_secret") or os.getenv("WEBHOOK_SECRET")

        # Set webhook
        instance.logger.info(f"Setting webhook to {webhook_url}")

        await instance.app.bot.set_webhook(
            url=webhook_url,
            secret_token=webhook_secret,
            allowed_updates=Update.ALL_TYPES
        )

        instance.logger.success("Webhook configured successfully")

    @staticmethod
    async def delete_webhook(instance: BotInstance) -> None:
        """
        Delete webhook (switch to polling)

        Args:
            instance: Bot instance
        """
        instance.logger.info("Deleting webhook...")
        await instance.app.bot.delete_webhook()
        instance.logger.success("Webhook deleted")

    @staticmethod
    async def get_webhook_info(instance: BotInstance) -> Dict[str, Any]:
        """
        Get webhook information

        Args:
            instance: Bot instance

        Returns:
            Webhook info dictionary
        """
        info = await instance.app.bot.get_webhook_info()
        return {
            "url": info.url,
            "has_custom_certificate": info.has_custom_certificate,
            "pending_update_count": info.pending_update_count,
            "last_error_date": info.last_error_date,
            "last_error_message": info.last_error_message,
            "max_connections": info.max_connections,
            "allowed_updates": info.allowed_updates
        }


async def create_webhook_app(instance: BotInstance) -> web.Application:
    """
    Create aiohttp application for webhook deployment

    Args:
        instance: Bot instance

    Returns:
        aiohttp web application
    """
    # Initialize bot
    await instance.start()

    # Create app
    app = web.Application()

    # Create handler
    handler = Deployer.create_serverless_handler(instance)

    # Add routes
    app.router.add_get("/", handler)
    app.router.add_get("/health", handler)
    app.router.add_post("/api/webhook", handler)

    return app
