# services/alert_processor/app/api/alerts.py
"""
Alerts API endpoints for dashboard and alert management
"""

from fastapi import APIRouter, HTTPException, Query, Path
from typing import List, Optional
from pydantic import BaseModel, Field
from uuid import UUID
from datetime import datetime
import structlog

from app.repositories.alerts_repository import AlertsRepository
from app.models.alerts import AlertSeverity, AlertStatus

logger = structlog.get_logger()

router = APIRouter()


# ============================================================
# Response Models
# ============================================================

class AlertResponse(BaseModel):
    """Individual alert response"""
    id: str
    tenant_id: str
    item_type: str
    alert_type: str
    severity: str
    status: str
    service: str
    title: str
    message: str
    actions: Optional[dict] = None
    alert_metadata: Optional[dict] = None
    created_at: datetime
    updated_at: datetime
    resolved_at: Optional[datetime] = None

    class Config:
        from_attributes = True


class AlertsSummaryResponse(BaseModel):
    """Alerts summary for dashboard"""
    total_count: int = Field(..., description="Total number of alerts")
    active_count: int = Field(..., description="Number of active (unresolved) alerts")
    critical_count: int = Field(..., description="Number of critical/urgent alerts")
    high_count: int = Field(..., description="Number of high severity alerts")
    medium_count: int = Field(..., description="Number of medium severity alerts")
    low_count: int = Field(..., description="Number of low severity alerts")
    resolved_count: int = Field(..., description="Number of resolved alerts")
    acknowledged_count: int = Field(..., description="Number of acknowledged alerts")


class AlertsListResponse(BaseModel):
    """List of alerts with pagination"""
    alerts: List[AlertResponse]
    total: int
    limit: int
    offset: int


# ============================================================
# API Endpoints
# ============================================================

@router.get(
    "/api/v1/tenants/{tenant_id}/alerts/summary",
    response_model=AlertsSummaryResponse,
    summary="Get alerts summary",
    description="Get summary of alerts by severity and status for dashboard health indicator"
)
async def get_alerts_summary(
    tenant_id: UUID = Path(..., description="Tenant ID")
) -> AlertsSummaryResponse:
    """
    Get alerts summary for dashboard

    Returns counts of alerts grouped by severity and status.
    Critical count maps to URGENT severity for dashboard compatibility.
    """
    from app.config import AlertProcessorConfig
    from shared.database.base import create_database_manager

    try:
        config = AlertProcessorConfig()
        db_manager = create_database_manager(config.DATABASE_URL, "alert-processor")

        async with db_manager.get_session() as session:
            repo = AlertsRepository(session)
            summary = await repo.get_alerts_summary(tenant_id)
            return AlertsSummaryResponse(**summary)

    except Exception as e:
        logger.error("Error getting alerts summary", error=str(e), tenant_id=str(tenant_id))
        raise HTTPException(status_code=500, detail=str(e))


@router.get(
    "/api/v1/tenants/{tenant_id}/alerts",
    response_model=AlertsListResponse,
    summary="Get alerts list",
    description="Get filtered list of alerts with pagination"
)
async def get_alerts(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    severity: Optional[str] = Query(None, description="Filter by severity: low, medium, high, urgent"),
    status: Optional[str] = Query(None, description="Filter by status: active, resolved, acknowledged, ignored"),
    resolved: Optional[bool] = Query(None, description="Filter by resolved status: true=resolved only, false=unresolved only"),
    limit: int = Query(100, ge=1, le=1000, description="Maximum number of results"),
    offset: int = Query(0, ge=0, description="Pagination offset")
) -> AlertsListResponse:
    """
    Get filtered list of alerts

    Supports filtering by:
    - severity: low, medium, high, urgent (maps to "critical" in dashboard)
    - status: active, resolved, acknowledged, ignored
    - resolved: boolean filter for resolved status
    - pagination: limit and offset
    """
    from app.config import AlertProcessorConfig
    from shared.database.base import create_database_manager

    try:
        # Validate severity enum
        if severity and severity not in [s.value for s in AlertSeverity]:
            raise HTTPException(
                status_code=400,
                detail=f"Invalid severity. Must be one of: {[s.value for s in AlertSeverity]}"
            )

        # Validate status enum
        if status and status not in [s.value for s in AlertStatus]:
            raise HTTPException(
                status_code=400,
                detail=f"Invalid status. Must be one of: {[s.value for s in AlertStatus]}"
            )

        config = AlertProcessorConfig()
        db_manager = create_database_manager(config.DATABASE_URL, "alert-processor")

        async with db_manager.get_session() as session:
            repo = AlertsRepository(session)
            alerts = await repo.get_alerts(
                tenant_id=tenant_id,
                severity=severity,
                status=status,
                resolved=resolved,
                limit=limit,
                offset=offset
            )

            # Convert to response models
            alert_responses = [
                AlertResponse(
                    id=str(alert.id),
                    tenant_id=str(alert.tenant_id),
                    item_type=alert.item_type,
                    alert_type=alert.alert_type,
                    severity=alert.severity,
                    status=alert.status,
                    service=alert.service,
                    title=alert.title,
                    message=alert.message,
                    actions=alert.actions,
                    alert_metadata=alert.alert_metadata,
                    created_at=alert.created_at,
                    updated_at=alert.updated_at,
                    resolved_at=alert.resolved_at
                )
                for alert in alerts
            ]

            return AlertsListResponse(
                alerts=alert_responses,
                total=len(alert_responses),  # In a real implementation, you'd query the total count separately
                limit=limit,
                offset=offset
            )

    except HTTPException:
        raise
    except Exception as e:
        logger.error("Error getting alerts", error=str(e), tenant_id=str(tenant_id))
        raise HTTPException(status_code=500, detail=str(e))


@router.get(
    "/api/v1/tenants/{tenant_id}/alerts/{alert_id}",
    response_model=AlertResponse,
    summary="Get alert by ID",
    description="Get a specific alert by its ID"
)
async def get_alert(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    alert_id: UUID = Path(..., description="Alert ID")
) -> AlertResponse:
    """Get a specific alert by ID"""
    from app.config import AlertProcessorConfig
    from shared.database.base import create_database_manager

    try:
        config = AlertProcessorConfig()
        db_manager = create_database_manager(config.DATABASE_URL, "alert-processor")

        async with db_manager.get_session() as session:
            repo = AlertsRepository(session)
            alert = await repo.get_alert_by_id(tenant_id, alert_id)

            if not alert:
                raise HTTPException(status_code=404, detail="Alert not found")

            return AlertResponse(
                id=str(alert.id),
                tenant_id=str(alert.tenant_id),
                item_type=alert.item_type,
                alert_type=alert.alert_type,
                severity=alert.severity,
                status=alert.status,
                service=alert.service,
                title=alert.title,
                message=alert.message,
                actions=alert.actions,
                alert_metadata=alert.alert_metadata,
                created_at=alert.created_at,
                updated_at=alert.updated_at,
                resolved_at=alert.resolved_at
            )

    except HTTPException:
        raise
    except Exception as e:
        logger.error("Error getting alert", error=str(e), alert_id=str(alert_id))
        raise HTTPException(status_code=500, detail=str(e))
