# shared/clients/alerts_client.py
"""
Alerts Service Client for Inter-Service Communication
Provides access to alert processor service from other services
"""

import structlog
from typing import Dict, Any, Optional, List
from uuid import UUID
from shared.clients.base_service_client import BaseServiceClient
from shared.config.base import BaseServiceSettings

logger = structlog.get_logger()


class AlertsServiceClient(BaseServiceClient):
    """Client for communicating with the Alert Processor Service"""

    def __init__(self, config: BaseServiceSettings, calling_service_name: str = "unknown"):
        super().__init__(calling_service_name, config)

    def get_service_base_path(self) -> str:
        return "/api/v1"

    # ================================================================
    # DASHBOARD METHODS
    # ================================================================

    async def get_alerts_summary(
        self,
        tenant_id: str
    ) -> Optional[Dict[str, Any]]:
        """
        Get alerts summary for dashboard health status

        Args:
            tenant_id: Tenant ID

        Returns:
            Dict with counts by severity:
            {
                "total_count": int,
                "active_count": int,
                "critical_count": int,  # Maps to "urgent" severity
                "high_count": int,
                "medium_count": int,
                "low_count": int,
                "resolved_count": int,
                "acknowledged_count": int
            }
        """
        try:
            # Gateway routes /tenants/{tenant_id}/alerts/... to alert_processor service
            return await self.get(
                "/alerts/summary",
                tenant_id=tenant_id
            )
        except Exception as e:
            logger.error("Error fetching alerts summary", error=str(e), tenant_id=tenant_id)
            return None

    async def get_critical_alerts(
        self,
        tenant_id: str,
        limit: int = 20
    ) -> Optional[Dict[str, Any]]:
        """
        Get critical/urgent alerts for dashboard

        Note: "critical" in dashboard context maps to "urgent" severity in alert_processor

        Args:
            tenant_id: Tenant ID
            limit: Maximum number of alerts to return

        Returns:
            Dict with:
            {
                "alerts": [...],
                "total": int,
                "limit": int,
                "offset": int
            }
        """
        try:
            # Gateway routes /tenants/{tenant_id}/alerts/... to alert_processor service
            # "critical" in dashboard = "urgent" severity in alert_processor
            return await self.get(
                "/alerts",
                tenant_id=tenant_id,
                params={"severity": "urgent", "resolved": False, "limit": limit}
            )
        except Exception as e:
            logger.error("Error fetching critical alerts", error=str(e), tenant_id=tenant_id)
            return None

    async def get_alerts(
        self,
        tenant_id: str,
        priority_level: Optional[str] = None,
        status: Optional[str] = None,
        resolved: Optional[bool] = None,
        limit: int = 100,
        offset: int = 0
    ) -> Optional[Dict[str, Any]]:
        """
        Get alerts with optional filters

        Args:
            tenant_id: Tenant ID
            priority_level: Filter by priority level (critical, important, standard, info)
            status: Filter by status (active, resolved, acknowledged, ignored)
            resolved: Filter by resolved status (None = all, True = resolved only, False = unresolved only)
            limit: Maximum number of alerts
            offset: Pagination offset

        Returns:
            Dict with:
            {
                "alerts": [...],
                "total": int,
                "limit": int,
                "offset": int
            }
        """
        try:
            params = {"limit": limit, "offset": offset}
            if priority_level:
                params["priority_level"] = priority_level
            if status:
                params["status"] = status
            if resolved is not None:
                params["resolved"] = resolved

            return await self.get(
                "/alerts",
                tenant_id=tenant_id,
                params=params
            )
        except Exception as e:
            logger.error("Error fetching alerts",
                       error=str(e), tenant_id=tenant_id)
            return None

    async def get_alerts_by_severity(
        self,
        tenant_id: str,
        severity: str,
        limit: int = 100,
        resolved: Optional[bool] = None
    ) -> Optional[Dict[str, Any]]:
        """
        Get alerts filtered by severity

        Args:
            tenant_id: Tenant ID
            severity: Severity level (low, medium, high, urgent)
            limit: Maximum number of alerts
            resolved: Filter by resolved status (None = all, True = resolved only, False = unresolved only)

        Returns:
            Dict with alerts list and metadata
        """
        try:
            params = {"severity": severity, "limit": limit}
            if resolved is not None:
                params["resolved"] = resolved

            return await self.get(
                "/alerts",
                tenant_id=tenant_id,
                params=params
            )
        except Exception as e:
            logger.error("Error fetching alerts by severity",
                       error=str(e), severity=severity, tenant_id=tenant_id)
            return None

    async def get_alert_by_id(
        self,
        tenant_id: str,
        alert_id: str
    ) -> Optional[Dict[str, Any]]:
        """
        Get a specific alert by ID

        Args:
            tenant_id: Tenant ID
            alert_id: Alert UUID

        Returns:
            Dict with alert details
        """
        try:
            return await self.get(
                f"/alerts/{alert_id}",
                tenant_id=tenant_id
            )
        except Exception as e:
            logger.error("Error fetching alert", error=str(e),
                       alert_id=alert_id, tenant_id=tenant_id)
            return None

    async def get_dashboard_analytics(
        self,
        tenant_id: str,
        days: int = 7
    ) -> Optional[Dict[str, Any]]:
        """
        Get dashboard analytics including prevented issues and estimated savings

        Args:
            tenant_id: Tenant ID
            days: Number of days to analyze (default: 7)

        Returns:
            Dict with analytics data:
            {
                "period_days": int,
                "total_alerts": int,
                "active_alerts": int,
                "ai_handling_rate": float,
                "prevented_issues_count": int,
                "estimated_savings_eur": float,
                "total_financial_impact_at_risk_eur": float,
                "priority_distribution": {...},
                "type_class_distribution": {...},
                "active_by_type_class": {...},
                "period_comparison": {...}
            }
        """
        try:
            return await self.get(
                "/alerts/analytics/dashboard",
                tenant_id=tenant_id,
                params={"days": days}
            )
        except Exception as e:
            logger.error("Error fetching dashboard analytics", error=str(e), tenant_id=tenant_id)
            return None

    # ================================================================
    # UTILITY METHODS
    # ================================================================

    async def health_check(self) -> bool:
        """Check if alerts service is healthy"""
        try:
            result = await self.get("../health")  # Health endpoint is not tenant-scoped
            return result is not None
        except Exception as e:
            logger.error("Alerts service health check failed", error=str(e))
            return False


# Factory function for dependency injection
def create_alerts_client(config: BaseServiceSettings, calling_service_name: str = "unknown") -> AlertsServiceClient:
    """Create alerts service client instance"""
    return AlertsServiceClient(config, calling_service_name)
