# src/fmatch/saas/api/v2/notifications.py
"""Notifications and outbox API endpoints."""

from fastapi import APIRouter, Query, HTTPException
from typing import Optional, Literal
from datetime import datetime
from pydantic import BaseModel

router = APIRouter(prefix="/api/v2/notifications", tags=["notifications"])


class OutboxMessage(BaseModel):
    id: str
    route_key: str
    channel: Optional[str]
    status: Literal["pending", "delivered", "failed"]
    attempt_count: int
    latency_ms: Optional[int]
    created_at: datetime
    updated_at: datetime
    error_message: Optional[str] = None


# Mock data for demonstration
MOCK_OUTBOX = [
    {
        "id": "msg-001",
        "route_key": "match_run_complete",
        "channel": "#general",
        "status": "delivered",
        "attempt_count": 1,
        "latency_ms": 245,
        "created_at": datetime.utcnow().isoformat(),
        "updated_at": datetime.utcnow().isoformat(),
        "error_message": None,
    },
    {
        "id": "msg-002",
        "route_key": "duplicates_found",
        "channel": "#data-alerts",
        "status": "delivered",
        "attempt_count": 1,
        "latency_ms": 189,
        "created_at": datetime.utcnow().isoformat(),
        "updated_at": datetime.utcnow().isoformat(),
        "error_message": None,
    },
    {
        "id": "msg-003",
        "route_key": "data_quality_alert",
        "channel": "#quality",
        "status": "pending",
        "attempt_count": 0,
        "latency_ms": None,
        "created_at": datetime.utcnow().isoformat(),
        "updated_at": datetime.utcnow().isoformat(),
        "error_message": None,
    },
]


@router.get("/outbox")
async def list_outbox(
    status: Optional[str] = Query(
        "pending", description="Filter by status (pending, delivered, failed, any)"
    ),
    limit: int = Query(50, ge=1, le=100),
    offset: int = Query(0, ge=0),
):
    """List notification outbox messages."""

    # Filter by status
    if status != "any":
        filtered = [m for m in MOCK_OUTBOX if m["status"] == status]
    else:
        filtered = MOCK_OUTBOX

    # Apply pagination
    paginated = filtered[offset : offset + limit]

    # Calculate totals
    total = len(filtered)
    delivered = len([m for m in MOCK_OUTBOX if m["status"] == "delivered"])
    failed = len([m for m in MOCK_OUTBOX if m["status"] == "failed"])
    pending = len([m for m in MOCK_OUTBOX if m["status"] == "pending"])

    return {
        "items": paginated,
        "total": total,
        "delivered": delivered,
        "failed": failed,
        "pending": pending,
        "offset": offset,
        "limit": limit,
    }


@router.post("/outbox/{message_id}/retry")
async def retry_outbox_message(message_id: str):
    """Retry a failed notification."""
    # Find the message
    message = next((m for m in MOCK_OUTBOX if m["id"] == message_id), None)
    if not message:
        raise HTTPException(status_code=404, detail="Message not found")

    if message["status"] != "failed":
        raise HTTPException(status_code=400, detail="Can only retry failed messages")

    # Update status to pending for retry
    message["status"] = "pending"
    message["attempt_count"] += 1
    message["updated_at"] = datetime.utcnow().isoformat()

    return {"message": "Message queued for retry", "message_id": message_id}


@router.delete("/outbox/{message_id}")
async def delete_outbox_message(message_id: str):
    """Delete a notification from the outbox."""
    global MOCK_OUTBOX
    MOCK_OUTBOX = [m for m in MOCK_OUTBOX if m["id"] != message_id]
    return {"message": "Message deleted", "message_id": message_id}
