from folkugat_web.dal.sql import Connection
from folkugat_web.dal.sql._connection import get_connection
from folkugat_web.dal.sql.playlists import query, write
from folkugat_web.log import logger
from folkugat_web.model import playlists
from folkugat_web.services.temes import links as links_service
from folkugat_web.services.temes import lyrics as lyrics_service
from folkugat_web.services.temes import query as temes_query
from folkugat_web.services.temes import scores as scores_service


def add_temes_to_playlist(playlist: playlists.Playlist) -> playlists.Playlist:
    for set_ in playlist.sets:
        _ = add_temes_to_set(set_)
    return playlist


def add_temes_to_set(set_: playlists.Set) -> playlists.Set:
    for tema_in_set in set_.temes:
        _ = add_tema_to_tema_in_set(tema_in_set)
    return set_


def add_tema_to_tema_in_set(tema_in_set: playlists.TemaInSet) -> playlists.TemaInSet:
    if tema_in_set.tema_id is not None:
        tema_in_set.tema = temes_query.get_tema_by_id(tema_in_set.tema_id)
        if not tema_in_set.tema:
            logger.error("fCould not load tune in set: {tema_in_set}")
        else:
            _ = links_service.add_links_to_tema(tema_in_set.tema)
            _ = lyrics_service.add_lyrics_to_tema(tema_in_set.tema)
            _ = scores_service.add_scores_to_tema(tema_in_set.tema)
    return tema_in_set


def get_playlist(session_id: int, con: Connection | None = None) -> playlists.Playlist:
    return playlists.Playlist.from_playlist_entries(
        session_id=session_id,
        entries=list(query.get_playlist_entries(session_id=session_id, con=con))
    )


def add_set(session_id: int, con: Connection | None = None) -> playlists.Set:
    with get_connection(con) as con:
        curr_playlist = get_playlist(session_id=session_id, con=con)
        new_set_id = max([set_entry.id for set_entry in curr_playlist.sets], default=0) + 1
        new_entry = playlists.PlaylistEntry(id=None, session_id=session_id, set_id=new_set_id, tema_id=None)
        inserted_entry = write.insert_playlist_entry(new_entry)
        return playlists.Set.from_playlist_entries(set_id=inserted_entry.set_id, entries=[inserted_entry])


def get_set(session_id: int, set_id: int, con: Connection | None = None) -> playlists.Set | None:
    entries = list(query.get_playlist_entries(session_id=session_id, set_id=set_id, con=con))
    if entries:
        return playlists.Set.from_playlist_entries(set_id=set_id, entries=entries)
    else:
        return None


def delete_set(session_id: int, set_id: int, con: Connection | None = None):
    write.delete_playlist_set(session_id=session_id, set_id=set_id, con=con)


def add_tema(session_id: int, set_id: int, con: Connection | None = None) -> playlists.TemaInSet:
    with get_connection(con) as con:
        new_entry = playlists.PlaylistEntry(id=None, session_id=session_id, set_id=set_id, tema_id=None)
        inserted_entry = write.insert_playlist_entry(new_entry)
        return playlists.TemaInSet.from_playlist_entry(inserted_entry)


def get_tema(entry_id: int, con: Connection | None = None) -> playlists.TemaInSet:
    with get_connection(con) as con:
        entry = next(query.get_playlist_entries(entry_id=entry_id))
        return playlists.TemaInSet.from_playlist_entry(entry)


def delete_tema(entry_id: int, con: Connection | None = None):
    with get_connection(con) as con:
        write.delete_playlist_entry(entry_id=entry_id, con=con)


def set_tema(session_id: int, set_id: int, entry_id: int, tema_id: int | None,
             con: Connection | None = None):
    with get_connection(con) as con:
        new_entry = playlists.PlaylistEntry(id=entry_id, session_id=session_id, set_id=set_id, tema_id=tema_id)
        write.update_playlist_entry(entry=new_entry, con=con)
