from fastapi import Request
from fastapi.responses import HTMLResponse
from folkugat_web.model.pagines import Pages
from folkugat_web.model.playlists import PlaylistType
from folkugat_web.services import playlists as playlists_service
from folkugat_web.services import sessions as sessions_service
from folkugat_web.services.temes import query as query_service
from folkugat_web.services.temes import search as search_service
from folkugat_web.templates import templates


def add_set(
    request: Request,
    playlist_id: int,
    logged_in: bool,
):
    new_set = playlists_service.add_set(playlist_id=playlist_id)
    return templates.TemplateResponse(
        "fragments/llista/set_entry.html",
        {
            "request": request,
            "logged_in": logged_in,
            "new_entry": True,
            "playlist_id": playlist_id,
            "set_id": new_set.id,
            "set_entry": new_set,
        }
    )


def get_set(request: Request, playlist_id: int, set_id: int, logged_in: bool):
    set_entry = playlists_service.get_set(playlist_id=playlist_id, set_id=set_id)
    if set_entry:
        return templates.TemplateResponse(
            "fragments/llista/set_entry.html",
            {
                "request": request,
                "logged_in": logged_in,
                "new_entry": True,
                "playlist_id": playlist_id,
                "set_id": set_id,
                "set_entry": set_entry,
            }
        )
    else:
        return HTMLResponse()


def delete_set(playlist_id: int, set_id: int):
    playlists_service.delete_set(playlist_id=playlist_id, set_id=set_id)
    return HTMLResponse()


def add_tema(request: Request, playlist_id: int, set_id: int, logged_in: bool):
    new_tema = playlists_service.add_tema(playlist_id=playlist_id, set_id=set_id)
    new_tema = playlists_service.add_tema_to_tema_in_set(new_tema)
    return templates.TemplateResponse(
        "fragments/llista/tema_editor.html",
        {
            "request": request,
            "logged_in": logged_in,
            "playlist_id": playlist_id,
            "set_id": set_id,
            "tema_entry": new_tema,
        }
    )


def get_tema(request: Request, playlist_id: int, set_id: int, entry_id: int, logged_in: bool):
    tema_entry = playlists_service.get_tema(entry_id=entry_id)
    tema_entry = playlists_service.add_tema_to_tema_in_set(tema_entry)
    return templates.TemplateResponse(
        "fragments/llista/tema_entry.html",
        {
            "request": request,
            "logged_in": logged_in,
            "playlist_id": playlist_id,
            "set_id": set_id,
            "tema_entry": tema_entry,
        }
    )


def get_tema_editor(request: Request, playlist_id: int, set_id: int, entry_id: int, logged_in: bool):
    tema_entry = playlists_service.get_tema(entry_id=entry_id)
    tema_entry = playlists_service.add_tema_to_tema_in_set(tema_entry)
    return templates.TemplateResponse(
        "fragments/llista/tema_editor.html",
        {
            "request": request,
            "logged_in": logged_in,
            "playlist_id": playlist_id,
            "set_id": set_id,
            "tema_entry": tema_entry,
        }
    )


def delete_tema(playlist_id: int, set_id: int, entry_id: int):
    playlists_service.delete_tema(entry_id=entry_id)
    if not playlists_service.get_set(playlist_id=playlist_id, set_id=set_id):
        headers = {
            "HX-Trigger": f"reload-set-{playlist_id}-{set_id}"
        }
    else:
        headers = {}
    return HTMLResponse(headers=headers)


def busca_tema(
    request: Request,
    playlist_id: int,
    set_id: int,
    entry_id: int,
    query: str,
):
    n_results = 4
    suggestions = []
    if not query:
        # If there is no query, suggest tunes commonly played together
        set_entry = playlists_service.get_set(
            playlist_id=playlist_id,
            set_id=set_id,
        )
        if set_entry:
            tema_ids = {tema_in_set.tema_id
                        for tema_in_set in set_entry.temes
                        if tema_in_set and tema_in_set.tema_id is not None}
            commonly_played_tema_ids = {
                cpt.tema.id
                for tema_id in tema_ids
                for cpt in sessions_service.get_commonly_played_temes(tema_id)
                if cpt.tema.id is not None
            } - tema_ids
            suggestions = query_service.get_temes_by_ids(
                tema_ids=list(commonly_played_tema_ids)
            )
    if len(suggestions) >= n_results:
        suggestions = suggestions[:n_results]
    elif not suggestions:
        suggestions = search_service.busca_temes(
            query=query,
            properties=[],
            hidden=True,
            limit=n_results,
            offset=0,
        )
    return templates.TemplateResponse(
        "fragments/llista/tema_results.html",
        {
            "request": request,
            "playlist_id": playlist_id,
            "set_id": set_id,
            "entry_id": entry_id,
            "results": suggestions,
            "query": query,
        }
    )


def set_tema(
    request: Request,
    logged_in: bool,
    playlist_id: int,
    set_id: int,
    entry_id: int,
    tema_id: int | None,
    score_id: int | None = None,
):
    playlists_service.set_tema(
        playlist_id=playlist_id, set_id=set_id, entry_id=entry_id, tema_id=tema_id, score_id=score_id
    )
    tema_entry = playlists_service.get_tema(entry_id=entry_id)
    tema_entry = playlists_service.add_tema_to_tema_in_set(tema_entry)
    return templates.TemplateResponse(
        "fragments/llista/tema_entry.html",
        {
            "request": request,
            "logged_in": logged_in,
            "playlist_id": playlist_id,
            "set_id": set_id,
            "tema_entry": tema_entry,
        }
    )


def set_tema_score(
    request: Request,
    logged_in: bool,
    playlist_id: int,
    set_id: int,
    entry_id: int,
    score_id: int | None,
):
    """Update only the score selection for an existing playlist entry."""
    # Get current entry to preserve tema_id
    current_entry = playlists_service.get_tema(entry_id=entry_id)
    playlists_service.set_tema(
        playlist_id=playlist_id,
        set_id=set_id,
        entry_id=entry_id,
        tema_id=current_entry.tema_id,
        score_id=score_id,
    )
    tema_entry = playlists_service.get_tema(entry_id=entry_id)
    tema_entry = playlists_service.add_tema_to_tema_in_set(tema_entry)
    return templates.TemplateResponse(
        "fragments/llista/tema_entry.html",
        {
            "request": request,
            "logged_in": logged_in,
            "playlist_id": playlist_id,
            "set_id": set_id,
            "tema_entry": tema_entry,
        }
    )


async def pagina(request: Request, playlist_id: int, logged_in: bool):
    playlist = playlists_service.get_playlist(playlist_id=playlist_id)
    if not playlist:
        from fastapi import HTTPException
        raise HTTPException(status_code=404, detail="Could not find playlist")
    playlist = playlists_service.add_temes_to_playlist(playlist)
    playlist = await playlists_service.add_playlist_score_to_playlist(playlist)
    return templates.TemplateResponse(
        "fragments/llista/pagina.html",
        {
            "request": request,
            "logged_in": logged_in,
            "playlist_id": playlist_id,
            "playlist": playlist,
            "Pages": Pages,
            "PlaylistType": PlaylistType
        }
    )


def name(request: Request, playlist_id: int, logged_in: bool):
    playlist = playlists_service.get_playlist(playlist_id=playlist_id)
    if not playlist:
        from fastapi import HTTPException
        raise HTTPException(status_code=404, detail="Could not find playlist")
    return templates.TemplateResponse(
        "fragments/llista/name.html",
        {
            "request": request,
            "logged_in": logged_in,
            "playlist_id": playlist_id,
            "playlist": playlist,
        }
    )


def name_editor(request: Request, playlist_id: int, logged_in: bool):
    playlist = playlists_service.get_playlist(playlist_id=playlist_id)
    if not playlist:
        from fastapi import HTTPException
        raise HTTPException(status_code=404, detail="Could not find playlist")
    return templates.TemplateResponse(
        "fragments/llista/editor/name.html",
        {
            "request": request,
            "logged_in": logged_in,
            "playlist_id": playlist_id,
            "playlist": playlist,
        }
    )


def visibility(request: Request, logged_in: bool, playlist):
    return templates.TemplateResponse(
        "fragments/llista/visibility.html",
        {
            "request": request,
            "logged_in": logged_in,
            "playlist": playlist,
        }
    )
