from sqlalchemy import select
from sqlalchemy.orm import Session

from app.db.models import Child
from app.db.models import Video as VideoModel
from app.schemas.models import UploadTokenRequest, VideoCreateRequest
from app.services import oss as oss_service


def verify_child_owner(db: Session, parent_user_id: int, child_id: int) -> Child | None:
    return db.scalar(
        select(Child).where(
            Child.id == child_id,
            Child.parent_user_id == parent_user_id,
            Child.status != "archived",
        )
    )


def create_upload_token(body: UploadTokenRequest) -> dict:
    object_key = oss_service.generate_object_key(body.child_id, body.file_name)
    return oss_service.create_upload_token(object_key, body.content_type, body.size)


def save_direct_upload(token: str, object_key: str, data: bytes) -> None:
    if not oss_service.validate_upload_token(token, object_key):
        raise ValueError("invalid_upload_token")
    oss_service.save_local_upload(object_key, data)
    oss_service.consume_upload_token(token, object_key)


def register_video(
    db: Session, user_id: int, body: VideoCreateRequest
) -> tuple[VideoModel | None, str | None]:
    child = verify_child_owner(db, user_id, body.child_id)
    if not child:
        return None, "child_not_found"

    existing = db.scalar(select(VideoModel).where(VideoModel.object_key == body.object_key))
    if existing:
        return existing, "duplicate"

    video = VideoModel(
        child_id=body.child_id,
        uploaded_by=user_id,
        scene=body.scene.value,
        object_key=body.object_key,
        status="uploaded",
    )
    db.add(video)
    db.commit()
    db.refresh(video)
    return video, None
