"""
FastAPI Dependencies

Dependency injection for the async API endpoints.
"""

import logging
from typing import Annotated

from fastapi import Depends, Header, HTTPException, Request

from backend.data.async_request_db import AsyncRequestDB
from backend.web.rate_limiter import RateLimiter

logger = logging.getLogger(__name__)

# Global instances (initialized in app startup)
_async_db: AsyncRequestDB | None = None
_rate_limiter: RateLimiter | None = None


def init_dependencies(db: AsyncRequestDB, rate_limiter: RateLimiter) -> None:
    """Initialize global dependency instances."""
    global _async_db, _rate_limiter
    _async_db = db
    _rate_limiter = rate_limiter


def get_async_db() -> AsyncRequestDB:
    """Get async request database instance."""
    if _async_db is None:
        raise RuntimeError("AsyncRequestDB not initialized")
    return _async_db


def get_rate_limiter() -> RateLimiter:
    """Get rate limiter instance."""
    if _rate_limiter is None:
        raise RuntimeError("RateLimiter not initialized")
    return _rate_limiter


async def verify_api_key(
    x_api_key: Annotated[str | None, Header()] = None,
) -> str:
    """
    Verify API key exists and is active.

    Raises:
        HTTPException: 401 if API key is missing or invalid
    """
    if not x_api_key:
        raise HTTPException(
            status_code=401,
            detail="X-API-Key header is required",
            headers={"WWW-Authenticate": "API-Key"},
        )

    db = get_async_db()
    if not db.is_valid_api_key(x_api_key):
        raise HTTPException(
            status_code=401,
            detail="Invalid or inactive API key",
            headers={"WWW-Authenticate": "API-Key"},
        )

    # Update usage tracking
    try:
        db.update_api_key_usage(x_api_key)
    except Exception as e:
        logger.warning(f"Failed to update API key usage: {e}")

    return x_api_key


async def check_submit_rate_limit(
    api_key: Annotated[str, Depends(verify_api_key)],
) -> str:
    """
    Check rate limit before processing submit request.

    Raises:
        HTTPException: 429 if rate limit exceeded
    """
    rate_limiter = get_rate_limiter()
    status = rate_limiter.check_submit_limit(api_key)

    if not status.allowed:
        headers = rate_limiter.get_rate_limit_headers(status)
        raise HTTPException(
            status_code=429,
            detail=status.reason or "Rate limit exceeded",
            headers=headers,
        )

    return api_key


async def check_poll_rate_limit(
    request: Request,
    api_key: Annotated[str, Depends(verify_api_key)],
) -> str:
    """
    Check poll rate limit to prevent abuse.

    Raises:
        HTTPException: 429 if polling too frequently
    """
    # Extract request_id from path parameters
    request_id = request.path_params.get("request_id")
    if not request_id:
        return api_key  # No request_id, skip poll limit check

    rate_limiter = get_rate_limiter()
    status = rate_limiter.check_poll_limit(api_key, request_id)

    if not status.allowed:
        headers = rate_limiter.get_rate_limit_headers(status)
        raise HTTPException(
            status_code=429,
            detail=status.reason or "Polling too frequently",
            headers=headers,
        )

    return api_key


# Type aliases for cleaner route signatures
ApiKeyDep = Annotated[str, Depends(verify_api_key)]
SubmitRateLimitDep = Annotated[str, Depends(check_submit_rate_limit)]
PollRateLimitDep = Annotated[str, Depends(check_poll_rate_limit)]
AsyncDBDep = Annotated[AsyncRequestDB, Depends(get_async_db)]
RateLimiterDep = Annotated[RateLimiter, Depends(get_rate_limiter)]
