"""
Camera router for camera discovery and information
"""
from fastapi import APIRouter, Depends, status, HTTPException, Query
from fastapi.responses import JSONResponse
import structlog

from schemas.camera import CameraListResponse, CameraDetailResponse
from services.camera_service import CameraService
from middleware.auth_middleware import require_viewer, get_current_user
from models.user import User

logger = structlog.get_logger()

router = APIRouter(
    prefix="/api/v1/cameras",
    tags=["cameras"]
)


@router.get(
    "",
    response_model=CameraListResponse,
    status_code=status.HTTP_200_OK,
    summary="List all cameras",
    description="Get list of all cameras discovered from GeViScope",
    dependencies=[Depends(require_viewer)]  # Requires at least viewer role
)
async def list_cameras(
    use_cache: bool = Query(True, description="Use Redis cache (60s TTL)"),
    current_user: User = Depends(require_viewer)
):
    """
    Get list of all cameras from GeViScope SDK Bridge

    **Authentication Required:**
    - Minimum role: Viewer (all authenticated users can read cameras)

    **Query Parameters:**
    - `use_cache`: Use Redis cache (default: true, TTL: 60s)

    **Response:**
    - `cameras`: List of camera objects
    - `total`: Total number of cameras

    **Caching:**
    - Results are cached in Redis for 60 seconds
    - Set `use_cache=false` to bypass cache and fetch fresh data

    **Camera Object:**
    - `id`: Camera ID (channel number)
    - `name`: Camera name
    - `description`: Camera description
    - `has_ptz`: PTZ capability flag
    - `has_video_sensor`: Video sensor flag
    - `status`: Camera status (online, offline, unknown)
    - `last_seen`: Last seen timestamp
    """
    camera_service = CameraService()

    logger.info("list_cameras_request",
               user_id=str(current_user.id),
               username=current_user.username,
               use_cache=use_cache)

    result = await camera_service.list_cameras(use_cache=use_cache)

    logger.info("list_cameras_response",
               user_id=str(current_user.id),
               count=result["total"])

    return result


@router.get(
    "/{camera_id}",
    response_model=CameraDetailResponse,
    status_code=status.HTTP_200_OK,
    summary="Get camera details",
    description="Get detailed information about a specific camera",
    dependencies=[Depends(require_viewer)]  # Requires at least viewer role
)
async def get_camera(
    camera_id: int,
    use_cache: bool = Query(True, description="Use Redis cache (60s TTL)"),
    current_user: User = Depends(require_viewer)
):
    """
    Get detailed information about a specific camera

    **Authentication Required:**
    - Minimum role: Viewer (all authenticated users can read cameras)

    **Path Parameters:**
    - `camera_id`: Camera ID (channel number)

    **Query Parameters:**
    - `use_cache`: Use Redis cache (default: true, TTL: 60s)

    **Response:**
    - Camera object with detailed information

    **Errors:**
    - `404 Not Found`: Camera with specified ID does not exist
    """
    camera_service = CameraService()

    logger.info("get_camera_request",
               user_id=str(current_user.id),
               username=current_user.username,
               camera_id=camera_id,
               use_cache=use_cache)

    camera = await camera_service.get_camera(camera_id, use_cache=use_cache)

    if not camera:
        logger.warning("camera_not_found",
                      user_id=str(current_user.id),
                      camera_id=camera_id)
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Camera with ID {camera_id} not found"
        )

    logger.info("get_camera_response",
               user_id=str(current_user.id),
               camera_id=camera_id)

    return camera


@router.post(
    "/refresh",
    response_model=CameraListResponse,
    status_code=status.HTTP_200_OK,
    summary="Refresh camera list",
    description="Force refresh camera list from SDK Bridge (bypass cache)",
    dependencies=[Depends(require_viewer)]
)
async def refresh_cameras(
    current_user: User = Depends(require_viewer)
):
    """
    Force refresh camera list from GeViScope SDK Bridge

    **Authentication Required:**
    - Minimum role: Viewer

    **Response:**
    - Fresh camera list from SDK Bridge

    **Note:**
    - This endpoint bypasses Redis cache and fetches fresh data
    - Use this when you need real-time camera status
    - Cache is automatically invalidated and updated with fresh data
    """
    camera_service = CameraService()

    logger.info("refresh_cameras_request",
               user_id=str(current_user.id),
               username=current_user.username)

    result = await camera_service.refresh_camera_list()

    logger.info("refresh_cameras_response",
               user_id=str(current_user.id),
               count=result["total"])

    return result


@router.get(
    "/search/{query}",
    response_model=CameraListResponse,
    status_code=status.HTTP_200_OK,
    summary="Search cameras",
    description="Search cameras by name or description",
    dependencies=[Depends(require_viewer)]
)
async def search_cameras(
    query: str,
    current_user: User = Depends(require_viewer)
):
    """
    Search cameras by name or description

    **Authentication Required:**
    - Minimum role: Viewer

    **Path Parameters:**
    - `query`: Search query string (case-insensitive)

    **Response:**
    - List of cameras matching the search query

    **Search:**
    - Searches camera name and description fields
    - Case-insensitive partial match
    """
    camera_service = CameraService()

    logger.info("search_cameras_request",
               user_id=str(current_user.id),
               username=current_user.username,
               query=query)

    cameras = await camera_service.search_cameras(query)

    logger.info("search_cameras_response",
               user_id=str(current_user.id),
               query=query,
               matches=len(cameras))

    return {
        "cameras": cameras,
        "total": len(cameras)
    }


@router.get(
    "/filter/online",
    response_model=CameraListResponse,
    status_code=status.HTTP_200_OK,
    summary="Get online cameras",
    description="Get list of online cameras only",
    dependencies=[Depends(require_viewer)]
)
async def get_online_cameras(
    current_user: User = Depends(require_viewer)
):
    """
    Get list of online cameras only

    **Authentication Required:**
    - Minimum role: Viewer

    **Response:**
    - List of cameras with status="online"
    """
    camera_service = CameraService()

    logger.info("get_online_cameras_request",
               user_id=str(current_user.id),
               username=current_user.username)

    cameras = await camera_service.get_online_cameras()

    logger.info("get_online_cameras_response",
               user_id=str(current_user.id),
               count=len(cameras))

    return {
        "cameras": cameras,
        "total": len(cameras)
    }


@router.get(
    "/filter/ptz",
    response_model=CameraListResponse,
    status_code=status.HTTP_200_OK,
    summary="Get PTZ cameras",
    description="Get list of cameras with PTZ capabilities",
    dependencies=[Depends(require_viewer)]
)
async def get_ptz_cameras(
    current_user: User = Depends(require_viewer)
):
    """
    Get list of cameras with PTZ capabilities

    **Authentication Required:**
    - Minimum role: Viewer

    **Response:**
    - List of cameras with has_ptz=true
    """
    camera_service = CameraService()

    logger.info("get_ptz_cameras_request",
               user_id=str(current_user.id),
               username=current_user.username)

    cameras = await camera_service.get_ptz_cameras()

    logger.info("get_ptz_cameras_response",
               user_id=str(current_user.id),
               count=len(cameras))

    return {
        "cameras": cameras,
        "total": len(cameras)
    }
