"""File streaming endpoint with HTTP Range support.

Extracted from fastapi_server.py (#1602).
"""

import logging

from fastapi import APIRouter, HTTPException, Query, Request
from fastapi.responses import Response, StreamingResponse

from nexus.contracts.constants import ROOT_ZONE_ID
from nexus.contracts.exceptions import NexusFileNotFoundError, NexusPermissionError
from nexus.server.streaming import _verify_stream_token

logger = logging.getLogger(__name__)

router = APIRouter(tags=["streaming"])


@router.get("/api/stream/{path:path}", response_model=None)
async def stream_file(
    request: Request,
    path: str,
    token: str = Query(..., description="Signed stream token"),
    zone_id: str = Query(ROOT_ZONE_ID, description="Zone ID"),
) -> Response | StreamingResponse:
    """Stream file content with HTTP Range support (RFC 9110).

    Used by the local backend when return_url=True is requested.
    The token is generated by _generate_download_url() and contains a signed
    expiration timestamp for security.
    """
    from nexus.server.range_utils import build_range_response

    # Verify token
    if not _verify_stream_token(token, f"/{path}", zone_id):
        raise HTTPException(status_code=403, detail="Invalid or expired stream token")

    nexus_fs = request.app.state.nexus_fs
    if nexus_fs is None:
        raise HTTPException(status_code=503, detail="NexusFS not available")

    try:
        full_path = f"/{path}"

        from nexus.contracts.types import OperationContext
        from nexus.server.fastapi_server import to_thread_with_timeout

        context = OperationContext(
            user_id="system",
            groups=[],
            zone_id=zone_id,
            subject_type="system",
            subject_id="stream",
        )

        meta = await to_thread_with_timeout(nexus_fs.stat, full_path, context=context)
        content_id = meta.get("content_id")
        if not content_id:
            raise HTTPException(status_code=500, detail="File has no content id")

        total_size = meta.get("size", 0)

        return build_range_response(
            request_headers=request.headers,
            content_generator=lambda s, e, cs: nexus_fs.stream_range(
                full_path, s, e, chunk_size=cs, context=context
            ),
            full_generator=lambda: nexus_fs.stream(full_path, context=context),
            total_size=total_size,
            etag=content_id,
            content_type="application/octet-stream",
            filename=path.split("/")[-1],
            extra_headers={"X-Content-Id": content_id},
        )

    except NexusFileNotFoundError:
        raise HTTPException(status_code=404, detail=f"File not found: /{path}") from None
    except NexusPermissionError as e:
        raise HTTPException(status_code=403, detail=str(e)) from None
    except Exception as e:
        logger.error(f"Stream error for /{path}: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Stream error: {e}") from e
