"""
Notification Tools

Multi-channel notification capabilities:
- Slack notifications
- Email notifications
- Webhook calls
- PagerDuty integration
"""

from __future__ import annotations

import json
import logging
import os
from dataclasses import dataclass, field
from datetime import datetime, timezone
from enum import Enum
from typing import Any

logger = logging.getLogger(__name__)


class NotificationChannel(str, Enum):
    """Notification channels."""
    SLACK = "slack"
    EMAIL = "email"
    WEBHOOK = "webhook"
    PAGERDUTY = "pagerduty"
    LOG = "log"


class NotificationSeverity(str, Enum):
    """Notification severity levels."""
    INFO = "info"
    WARNING = "warning"
    ERROR = "error"
    CRITICAL = "critical"


@dataclass
class NotificationResult:
    """Result of a notification attempt."""
    success: bool
    channel: NotificationChannel
    message_id: str | None = None
    error: str | None = None
    sent_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))


class NotificationTools:
    """Tools for sending notifications across multiple channels."""

    def __init__(
        self,
        slack_webhook_url: str | None = None,
        pagerduty_key: str | None = None,
        smtp_config: dict | None = None,
    ):
        """
        Initialize notification tools.

        Args:
            slack_webhook_url: Slack incoming webhook URL
            pagerduty_key: PagerDuty routing key
            smtp_config: SMTP configuration for email
        """
        self.slack_webhook_url = slack_webhook_url or os.environ.get("SLACK_WEBHOOK_URL")
        self.pagerduty_key = pagerduty_key or os.environ.get("PAGERDUTY_ROUTING_KEY")
        self.smtp_config = smtp_config or {
            "host": os.environ.get("SMTP_HOST", "localhost"),
            "port": int(os.environ.get("SMTP_PORT", "587")),
            "user": os.environ.get("SMTP_USER"),
            "password": os.environ.get("SMTP_PASSWORD"),
        }
        self._notification_history: list[NotificationResult] = []
        logger.info("NotificationTools initialized")

    async def send_slack(
        self,
        message: str,
        channel: str | None = None,
        severity: str = "info",
        blocks: list[dict] | None = None,
    ) -> dict[str, Any]:
        """
        Send a Slack notification.

        Args:
            message: Message text
            channel: Slack channel (optional, uses webhook default)
            severity: Message severity for formatting
            blocks: Slack Block Kit blocks for rich formatting
        """
        if not self.slack_webhook_url:
            return {"success": False, "error": "Slack webhook URL not configured"}

        try:
            import httpx

            # Severity to emoji
            emoji_map = {
                "info": ":information_source:",
                "warning": ":warning:",
                "error": ":x:",
                "critical": ":rotating_light:",
            }
            emoji = emoji_map.get(severity, ":speech_balloon:")

            payload = {
                "text": f"{emoji} {message}",
            }

            if channel:
                payload["channel"] = channel

            if blocks:
                payload["blocks"] = blocks

            async with httpx.AsyncClient() as client:
                response = await client.post(
                    self.slack_webhook_url,
                    json=payload,
                    timeout=10.0,
                )
                response.raise_for_status()

            result = NotificationResult(
                success=True,
                channel=NotificationChannel.SLACK,
                message_id=None,
            )
            self._notification_history.append(result)

            return {
                "success": True,
                "channel": "slack",
                "message": message[:100],
            }

        except Exception as e:
            result = NotificationResult(
                success=False,
                channel=NotificationChannel.SLACK,
                error=str(e),
            )
            self._notification_history.append(result)
            return {"success": False, "error": str(e)}

    async def send_webhook(
        self,
        url: str,
        payload: dict[str, Any],
        method: str = "POST",
        headers: dict[str, str] | None = None,
    ) -> dict[str, Any]:
        """
        Send a webhook notification.

        Args:
            url: Webhook URL
            payload: JSON payload to send
            method: HTTP method (POST, PUT)
            headers: Additional headers
        """
        try:
            import httpx

            async with httpx.AsyncClient() as client:
                if method.upper() == "POST":
                    response = await client.post(
                        url,
                        json=payload,
                        headers=headers or {},
                        timeout=30.0,
                    )
                else:
                    response = await client.put(
                        url,
                        json=payload,
                        headers=headers or {},
                        timeout=30.0,
                    )

            return {
                "success": True,
                "status_code": response.status_code,
                "response": response.text[:500] if response.text else None,
            }

        except Exception as e:
            return {"success": False, "error": str(e)}

    async def send_pagerduty(
        self,
        summary: str,
        severity: str = "warning",
        source: str = "bgf-agents",
        dedup_key: str | None = None,
        custom_details: dict | None = None,
    ) -> dict[str, Any]:
        """
        Send a PagerDuty alert.

        Args:
            summary: Alert summary
            severity: Severity level (info, warning, error, critical)
            source: Source of the alert
            dedup_key: Deduplication key for grouping
            custom_details: Additional details
        """
        if not self.pagerduty_key:
            return {"success": False, "error": "PagerDuty routing key not configured"}

        try:
            import httpx

            # Map severity to PagerDuty severity
            pd_severity_map = {
                "info": "info",
                "warning": "warning",
                "error": "error",
                "critical": "critical",
            }

            payload = {
                "routing_key": self.pagerduty_key,
                "event_action": "trigger",
                "dedup_key": dedup_key,
                "payload": {
                    "summary": summary,
                    "severity": pd_severity_map.get(severity, "warning"),
                    "source": source,
                    "timestamp": datetime.now(timezone.utc).isoformat(),
                    "custom_details": custom_details or {},
                },
            }

            async with httpx.AsyncClient() as client:
                response = await client.post(
                    "https://events.pagerduty.com/v2/enqueue",
                    json=payload,
                    timeout=10.0,
                )
                response.raise_for_status()
                data = response.json()

            return {
                "success": True,
                "status": data.get("status"),
                "message": data.get("message"),
                "dedup_key": data.get("dedup_key"),
            }

        except Exception as e:
            return {"success": False, "error": str(e)}

    async def resolve_pagerduty(
        self,
        dedup_key: str,
    ) -> dict[str, Any]:
        """
        Resolve a PagerDuty incident.

        Args:
            dedup_key: Deduplication key of the incident to resolve
        """
        if not self.pagerduty_key:
            return {"success": False, "error": "PagerDuty routing key not configured"}

        try:
            import httpx

            payload = {
                "routing_key": self.pagerduty_key,
                "event_action": "resolve",
                "dedup_key": dedup_key,
            }

            async with httpx.AsyncClient() as client:
                response = await client.post(
                    "https://events.pagerduty.com/v2/enqueue",
                    json=payload,
                    timeout=10.0,
                )
                response.raise_for_status()

            return {"success": True, "resolved": dedup_key}

        except Exception as e:
            return {"success": False, "error": str(e)}

    def get_notification_history(self, limit: int = 50) -> list[dict[str, Any]]:
        """Get recent notification history."""
        return [
            {
                "success": n.success,
                "channel": n.channel.value,
                "message_id": n.message_id,
                "error": n.error,
                "sent_at": n.sent_at.isoformat(),
            }
            for n in self._notification_history[-limit:]
        ]


# Tool definitions for Claude Agent SDK
NOTIFICATION_TOOLS = [
    {
        "name": "send_slack",
        "description": "Send a notification to Slack.",
        "input_schema": {
            "type": "object",
            "properties": {
                "message": {"type": "string", "description": "Message to send"},
                "channel": {"type": "string", "description": "Slack channel (optional)"},
                "severity": {
                    "type": "string",
                    "description": "Message severity",
                    "enum": ["info", "warning", "error", "critical"],
                    "default": "info",
                },
            },
            "required": ["message"],
        },
    },
    {
        "name": "send_webhook",
        "description": "Send a notification to a webhook URL.",
        "input_schema": {
            "type": "object",
            "properties": {
                "url": {"type": "string", "description": "Webhook URL"},
                "payload": {"type": "object", "description": "JSON payload to send"},
                "method": {"type": "string", "description": "HTTP method", "default": "POST"},
                "headers": {"type": "object", "description": "Additional headers"},
            },
            "required": ["url", "payload"],
        },
    },
    {
        "name": "send_pagerduty",
        "description": "Send an alert to PagerDuty.",
        "input_schema": {
            "type": "object",
            "properties": {
                "summary": {"type": "string", "description": "Alert summary"},
                "severity": {
                    "type": "string",
                    "description": "Severity level",
                    "enum": ["info", "warning", "error", "critical"],
                    "default": "warning",
                },
                "source": {"type": "string", "description": "Source of the alert", "default": "bgf-agents"},
                "dedup_key": {"type": "string", "description": "Deduplication key for grouping"},
                "custom_details": {"type": "object", "description": "Additional details"},
            },
            "required": ["summary"],
        },
    },
    {
        "name": "resolve_pagerduty",
        "description": "Resolve a PagerDuty incident.",
        "input_schema": {
            "type": "object",
            "properties": {
                "dedup_key": {"type": "string", "description": "Deduplication key of incident to resolve"},
            },
            "required": ["dedup_key"],
        },
    },
    {
        "name": "get_notification_history",
        "description": "Get recent notification history.",
        "input_schema": {
            "type": "object",
            "properties": {
                "limit": {"type": "integer", "description": "Number of notifications to return", "default": 50},
            },
        },
    },
]


__all__ = ["NotificationTools", "NOTIFICATION_TOOLS", "NotificationChannel", "NotificationSeverity"]
