"""cortex/api/routes/admin/request_logs.py — Request log endpoints."""

from __future__ import annotations

import logging
from typing import Any, Dict, List, Optional

from fastapi import APIRouter, Depends, HTTPException, Response
from fastapi.responses import JSONResponse

from cortex.api.deps import PREFIX, _serialise, get_plugin
from cortex.api.deprecation import add_deprecation_headers
from cortex.api.models import RequestLogResponse

logger = logging.getLogger(__name__)


def _register(router: APIRouter, verify_api_key):
    """Register request log routes on the given router."""

    # ---- CANONICAL: /admin/requests  (properly namespaced — issue #297) ----
    @router.get(
        f"{PREFIX}/admin/requests",
        response_model=RequestLogResponse,
        summary="Paginated request log",
        tags=["admin"],
        operation_id="admin_get_request_log",
    )
    async def admin_get_request_log(
        request_type: Optional[str] = None,
        limit: int = 50,
        offset: int = 0,
        after: Optional[str] = None,
        _: None = Depends(verify_api_key),
        plugin: Any = Depends(get_plugin),
    ) -> RequestLogResponse:
        """Return a paginated view of the request log.

        Canonical path: ``GET /api/v1/admin/requests``.
        """
        return await _get_request_log_impl(
            request_type=request_type, limit=limit, offset=offset, after=after, plugin=plugin
        )

    # ---- DEPRECATED: /requests  (un-namespaced — issue #297) ----
    @router.get(
        f"{PREFIX}/requests",
        response_model=RequestLogResponse,
        summary="Paginated request log — DEPRECATED, use /admin/requests",
        tags=["system (deprecated)"],
        operation_id="get_request_log",
        deprecated=True,
    )
    async def get_request_log(
        request_type: Optional[str] = None,
        limit: int = 50,
        offset: int = 0,
        after: Optional[str] = None,
        response: Response = None,
        _: None = Depends(verify_api_key),
        plugin: Any = Depends(get_plugin),
    ) -> RequestLogResponse:
        """Return a paginated view of the request log.

        .. deprecated::
            Use ``GET /api/v1/admin/requests``.
            Sunset: 2026-06-01  (issue #297)
        """
        if response is not None:
            add_deprecation_headers(response, f"{PREFIX}/admin/requests")
        return await _get_request_log_impl(
            request_type=request_type, limit=limit, offset=offset, after=after, plugin=plugin
        )

    async def _get_request_log_impl(
        request_type, limit, offset, after, plugin
    ) -> RequestLogResponse:
        """Shared implementation for request-log endpoints."""
        errors: List[str] = []
        items: List[Dict[str, Any]] = []
        total = 0

        storage = getattr(plugin, "storage", None)
        if storage is None:
            errors.append("Storage not available")
            return RequestLogResponse(errors=errors)

        if not hasattr(storage, "get_request_log"):
            errors.append("Request log not supported by storage")
            return RequestLogResponse(errors=errors)

        owner_id = getattr(plugin.config, "owner_id", "default")

        try:
            rows = await storage.get_request_log(
                owner_id=owner_id,
                request_type=request_type,
                limit=limit,
                offset=offset,
            )

            if after is not None:
                from datetime import datetime, timezone
                try:
                    after_dt = datetime.fromisoformat(after.replace("Z", "+00:00"))
                    filtered = []
                    for row in rows:
                        created_at = row.get("created_at")
                        if created_at is None:
                            filtered.append(row)
                            continue
                        if isinstance(created_at, str):
                            try:
                                row_dt = datetime.fromisoformat(created_at.replace("Z", "+00:00"))
                            except ValueError:
                                filtered.append(row)
                                continue
                        elif isinstance(created_at, (int, float)):
                            row_dt = datetime.fromtimestamp(created_at, tz=timezone.utc)
                        else:
                            filtered.append(row)
                            continue
                        if row_dt > after_dt:
                            filtered.append(row)
                    rows = filtered
                except (ValueError, TypeError) as exc:
                    errors.append(f"Invalid 'after' datetime: {exc}")

            items = [_serialise(row) for row in rows]
            total = len(items)
        except Exception as exc:
            err = f"Request log query failed: {exc}"
            logger.error(err, exc_info=True)
            errors.append(err)

        return RequestLogResponse(items=items, total=total, errors=errors)

    @router.post(
        f"{PREFIX}/admin/prune-logs",
        summary="Prune old event_log and request_log rows",
        tags=["admin"],
    )
    async def prune_logs(
        retention_days: Optional[int] = None,
        _: None = Depends(verify_api_key),
        plugin: Any = Depends(get_plugin),
    ):
        """Delete event_log and request_log rows older than *retention_days*.

        Uses ``config.log_retention_days`` (default 90) when ``retention_days``
        is not supplied.  Returns the row counts deleted from each table.
        """
        storage = plugin.storage
        if storage is None:
            raise HTTPException(status_code=503, detail="Storage unavailable")
        if not hasattr(storage, "prune_old_logs"):
            raise HTTPException(status_code=501, detail="Storage backend does not support log pruning")

        days = retention_days if retention_days is not None else getattr(plugin.config, "log_retention_days", 90)
        try:
            result = await storage.prune_old_logs(retention_days=days)
        except Exception as exc:
            logger.error("prune_logs error: %s", exc, exc_info=True)
            raise HTTPException(status_code=500, detail="Internal server error")

        return {"pruned": result, "retention_days": days}
