from datetime import datetime
from typing import Annotated, Literal

from fastapi import APIRouter, Depends, Query

from app.config import Settings, get_settings
from app.dependencies import get_clip_service, get_storage_service, require_auth
from app.schemas.clip import Clip, ClipSearchResponse, PlaybackResponse, ThumbnailResponse
from app.services.clip_service import ClipService
from app.services.storage_service import StorageService

router = APIRouter(prefix="/api/clips", tags=["Clips"], dependencies=[Depends(require_auth)])


@router.get("", response_model=ClipSearchResponse, summary="Search clips with pagination and filters")
async def search_clips(
    clip_service: Annotated[ClipService, Depends(get_clip_service)],
    camera_id: int | None = None,
    detected_object: str | None = None,
    start: datetime | None = None,
    end: datetime | None = None,
    page: int = Query(default=1, ge=1),
    limit: int = Query(default=50, ge=1, le=500),
    sort: Literal["asc", "desc"] = "desc",
) -> ClipSearchResponse:
    items, total = await clip_service.search_clips(camera_id, detected_object, start, end, page, limit, sort)
    return ClipSearchResponse(items=items, page=page, limit=limit, total=total)


@router.get("/{clip_id}", response_model=Clip, summary="Get clip details")
async def get_clip(clip_id: str, clip_service: Annotated[ClipService, Depends(get_clip_service)]) -> Clip:
    return await clip_service.get_clip(clip_id)


@router.get("/{clip_id}/playback", response_model=PlaybackResponse, summary="Create a signed video playback URL")
async def get_playback_url(
    clip_id: str,
    clip_service: Annotated[ClipService, Depends(get_clip_service)],
    storage_service: Annotated[StorageService, Depends(get_storage_service)],
    settings: Annotated[Settings, Depends(get_settings)],
) -> PlaybackResponse:
    clip = await clip_service.get_clip(clip_id)
    url = await storage_service.get_signed_video_url(clip)
    return PlaybackResponse(url=url, expires_in=settings.signed_url_expiration_seconds)


@router.get("/{clip_id}/thumbnail", response_model=ThumbnailResponse, summary="Create a signed thumbnail URL")
async def get_thumbnail_url(
    clip_id: str,
    clip_service: Annotated[ClipService, Depends(get_clip_service)],
    storage_service: Annotated[StorageService, Depends(get_storage_service)],
) -> ThumbnailResponse:
    clip = await clip_service.get_clip(clip_id)
    url = await storage_service.get_signed_thumbnail_url(clip)
    return ThumbnailResponse(url=url)
