from fastapi import APIRouter, Depends, Header, Request
from fastapi.responses import JSONResponse, Response
from sqlalchemy.orm import Session

from app.core.response import error, ok
from app.db.models import User
from app.db.session import get_db
from app.deps import get_current_user
from app.schemas.models import UploadTokenRequest, VideoCreateRequest
from app.services import videos as video_service

router = APIRouter(prefix="/api/videos", tags=["Videos"])


@router.post("/upload-token")
def create_upload_token(
    body: UploadTokenRequest,
    request: Request,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    if not video_service.verify_child_owner(db, current_user.id, body.child_id):
        return JSONResponse(
            status_code=404,
            content=error(10004, "child_not_found", request.state.request_id),
        )
    data = video_service.create_upload_token(body)
    return ok(data, request_id=request.state.request_id)


@router.put("/direct-upload")
async def direct_upload(
    request: Request,
    x_upload_token: str = Header(..., alias="X-Upload-Token"),
    x_object_key: str = Header(..., alias="X-Object-Key"),
):
    data = await request.body()
    try:
        video_service.save_direct_upload(x_upload_token, x_object_key, data)
    except ValueError:
        return JSONResponse(
            status_code=403,
            content=error(10011, "invalid_upload_token", request.state.request_id),
        )
    return Response(status_code=204)


@router.post("", status_code=201)
def register_video(
    body: VideoCreateRequest,
    request: Request,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    video, err = video_service.register_video(db, current_user.id, body)
    if err == "child_not_found":
        return JSONResponse(
            status_code=404,
            content=error(10004, "child_not_found", request.state.request_id),
        )
    if err == "duplicate":
        return JSONResponse(
            status_code=409,
            content=error(10005, "duplicate_video", request.state.request_id),
        )
    return ok(
        {"id": video.id, "status": video.status},
        message="created",
        request_id=request.state.request_id,
    )
