"""API key authentication dependency for /v1/dashboard/* routes.

Validates X-API-Key header via SHA-256 hash lookup in Firestore api_keys
collection. Returns APIKeyContext with customer tier and feature info.
"""

from __future__ import annotations

import hashlib
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any

from fastapi.responses import JSONResponse

if TYPE_CHECKING:
    from fastapi import Request


@dataclass
class APIKeyContext:
    """Resolved context from a valid API key."""

    customer_id: str
    email: str
    tier: str
    features: list[str]
    project_limit: int | None
    batch_limit: int | None


class APIKeyAuthError(Exception):
    """Raised when API key validation fails."""

    def __init__(self, status_code: int, detail: str) -> None:
        self.status_code = status_code
        self.detail = detail
        super().__init__(detail)


async def require_api_key(request: Request) -> APIKeyContext:
    """Validate API key from X-API-Key header.

    1. Read X-API-Key header — 401 if missing
    2. SHA-256 hash the key
    3. Query Firestore api_keys WHERE key_hash == hash AND status == "active"
    4. If no match → 401 "Invalid API key"
    5. Look up customer from api_keys doc → return APIKeyContext
    """
    from backend.shared.firestore import get_customer, get_db

    api_key = request.headers.get("X-API-Key")
    if not api_key:
        raise APIKeyAuthError(401, "Missing X-API-Key header")

    key_hash = hashlib.sha256(api_key.encode()).hexdigest()

    doc = await get_db().collection("api_keys").document(key_hash).get()
    if not doc.exists:
        raise APIKeyAuthError(401, "Invalid API key")

    key_data: dict[str, Any] = doc.to_dict()  # type: ignore[assignment]
    if key_data.get("status") != "active":
        raise APIKeyAuthError(401, "Invalid API key")

    customer_id = key_data.get("customer_id", "")
    if not customer_id:
        raise APIKeyAuthError(401, "Invalid API key")

    customer = await get_customer(customer_id)
    if customer is None:
        raise APIKeyAuthError(401, "Invalid API key")

    from backend.shared.tier_config import TIER_CONFIG

    tier = customer.get("tier", "community")
    tier_cfg = TIER_CONFIG.get(tier, TIER_CONFIG["community"])
    features: list[str] = [str(f) for f in tier_cfg.get("features", [])]
    project_limit_raw = tier_cfg.get("project_limit")
    project_limit = int(project_limit_raw) if project_limit_raw is not None else None
    batch_limit_raw = tier_cfg.get("batch_limit")
    batch_limit = int(batch_limit_raw) if batch_limit_raw is not None else None

    return APIKeyContext(
        customer_id=customer_id,
        email=customer.get("email", ""),
        tier=tier,
        features=features,
        project_limit=project_limit,
        batch_limit=batch_limit,
    )


def api_key_auth_error_response(exc: APIKeyAuthError) -> JSONResponse:
    """Convert APIKeyAuthError to JSONResponse."""
    return JSONResponse(
        {"error": exc.detail},
        status_code=exc.status_code,
    )
