from fastapi import APIRouter, status, HTTPException, Depends
from sqlalchemy import select, Sequence
from src.core.log_conf import logger
from src.apis.utils import SessionDep
from src.db.repository.media import create_new_mediaactorfile, create_new_mediafile
from src.schema.media.actor import MediaActorResponse
from src.schema.media.actorfile import MediaActorFileResponse
from src.schema.media.file import MediaFileResponse, Link, get_file_details, set_file
from src.db.models.media import MediaFile

router = APIRouter()

@router.get("/update-titles")
def update_titles(db: SessionDep) -> list[MediaFileResponse]:
    results: list[MediaFileResponse] = []
    files = db.query(MediaFile).filter(MediaFile.review == True).all()
    for mediafile in files:
        mediafile.update_title()
        db.add(mediafile)
        response = get_file_details(mediafile)
        results.append(response)
    db.commit()
    return results


@router.get("/files", response_model=list[MediaFileResponse])
# def get_all_files(db: SessionDep, review: bool = False, download: bool = False, current_user: Profile = Depends(get_current_user_from_token)) -> List[MediaFileResponse]:
def get_all_files(db: SessionDep, review: bool = False, download: bool = False) -> list[MediaFileResponse]:
    results: list[MediaFileResponse] = []
    files: Sequence[MediaFile]
    if review:
        files = db.query(MediaFile).filter(MediaFile.review == True).all() # type: ignore
    elif download:
        files = db.query(MediaFile).filter(MediaFile.should_download == True).all() # type: ignore
    else:
        files = db.scalars(select(MediaFile)).all() # type: ignore
    for mediafile in files: # type: ignore
        response = get_file_details(mediafile)
        results.append(response)
    return results

@router.get("/files/{file_id}", response_model=MediaFileResponse)
def get_file(file_id: str, db: SessionDep) -> MediaFileResponse:
    mediafile = db.get(MediaFile, file_id)
    if not mediafile:
        raise HTTPException(status_code=404, detail="MediaFile could not be found")
    response = get_file_details(mediafile)
    return response

@router.get("/files/{file_id}/actors", response_model=list[MediaActorResponse])
def get_file_actors(file_id: str, db: SessionDep) -> list[MediaActorResponse]:
    mediafile = db.get(MediaFile, file_id)
    if not mediafile:
        raise HTTPException(status_code=404, detail="MediaFile could not be found")
    actor_files = mediafile.media_actor_files
    logger.info(f"already known actors: {actor_files}")
    results: list[MediaActorResponse] = []
    for actor_file in actor_files:
        response = MediaActorResponse(id=actor_file.media_actor.id, name=actor_file.media_actor.name, url=actor_file.media_actor.url)
        results.append(response)
    return results

@router.put("/files/{file_id}/actors", response_model=list[MediaActorFileResponse])
def update_file_actors(file_id: str, db: SessionDep, actors: list[MediaActorResponse]) -> list[MediaActorFileResponse]:
    mediafile = db.get(MediaFile, file_id)
    if not mediafile:
        raise HTTPException(status_code=404, detail="MediaFile could not be found")
    actor_files = mediafile.media_actor_files
    logger.info(f"already known actors: {actor_files}")
    for actor in actors:
        already_associated = False
        for actor_file in actor_files:
            if actor.id == actor_file.media_actor_id:
                logger.info("alreay associated - do nothing")
                already_associated = True
                break
        if not already_associated:
            create_new_mediaactorfile(db, actor.id, mediafile.id)
    db.refresh(mediafile)
    actor_files = mediafile.media_actor_files
    results: list[MediaActorFileResponse] = []
    for actor_file in actor_files:
        response = MediaActorFileResponse(id=actor_file.id, actor_id=actor_file.media_actor_id, file_id=actor_file.media_file_id)
        results.append(response)
    return results

@router.put("/files/{file_id}", response_model=MediaFileResponse)
def update_file(file_id: str, db: SessionDep, info: MediaFileResponse) -> MediaFileResponse:
    mediaFile = db.get(MediaFile, file_id)
    if not mediaFile:
        raise HTTPException(status_code=404, detail="MediaFile could not be found")
    set_file(info, mediaFile)
    db.add(mediaFile)
    db.commit()
    mediafile = db.get(MediaFile, file_id)
    if not mediafile:
        raise HTTPException(status_code=404, detail="MediaFile could not be updated")
    response = get_file_details(mediafile)
    return response

@router.post("/files", status_code=status.HTTP_201_CREATED)
def add_file(new_link: Link, db: SessionDep) -> MediaFileResponse:
    logger.info(f"add url {new_link.url}")
    try:
        mediaFile: MediaFile = create_new_mediafile(new_link.url, db)
    except:
        raise HTTPException(status_code=409, detail="Link duplicate")
    response = get_file_details(mediaFile)
    return response
