from PyQt5.QtCore import Qt

from app import playlists
from app import models
from app import musicmuster
from app import dbconfig


def seed2tracks(session):
    tracks = [
        {
            "path": "testdata/isa.mp3",
            "title": "I'm so afraid",
            "artist": "Fleetwood Mac",
            "duration": 263000,
            "start_gap": 60,
            "fade_at": 236263,
            "silence_at": 260343,
            "mtime": 371900000,
        },
        {
            "path": "testdata/mom.mp3",
            "title": "Man of Mystery",
            "artist": "The Shadows",
            "duration": 120000,
            "start_gap": 70,
            "fade_at": 115000,
            "silence_at": 118000,
            "mtime": 1642760000,
        },
    ]

    for track in tracks:
        db_track = models.Tracks(session=session, **track)
        session.add(db_track)

    session.commit()


def test_init(qtbot, session):
    """Just check we can create a playlist_tab"""

    playlist = models.Playlists(session, "my playlist")
    playlist_tab = playlists.PlaylistTab(None, session, playlist.id)
    assert playlist_tab


def test_save_and_restore(qtbot, session):
    """Playlist with one track, one note, save and restore"""

    # Create playlist
    playlist = models.Playlists(session, "my playlist")
    playlist_tab = playlists.PlaylistTab(None, session, playlist.id)

    # Insert a note
    note_text = "my note"
    note_row = 7
    note = models.Notes(session, playlist.id, note_row, note_text)
    playlist_tab._insert_note(session, note)

    # Add a track
    track_path = "/a/b/c"
    track = models.Tracks(session, track_path)
    # Inserting the track will also save the playlist
    playlist_tab.insert_track(session, track)

    # We need to commit the session before re-querying
    session.commit()

    # Retrieve playlist
    all_playlists = playlists.Playlists.get_open(session)
    assert len(all_playlists) == 1
    retrieved_playlist = all_playlists[0]
    paths = [a.path for a in retrieved_playlist.tracks.values()]
    assert track_path in paths
    notes = [a.note for a in retrieved_playlist.notes]
    assert note_text in notes


def test_meta_all_clear(qtbot, session):

    # Create playlist
    playlist = models.Playlists(session, "my playlist")
    playlist_tab = playlists.PlaylistTab(None, session, playlist.id)

    # Add some tracks
    # Need to commit session after each one so that new row is found
    # for subsequent inserts
    track1_path = "/a/b/c"
    track1 = models.Tracks(session, track1_path)
    playlist_tab.insert_track(session, track1)
    session.commit()
    track2_path = "/d/e/f"
    track2 = models.Tracks(session, track2_path)
    playlist_tab.insert_track(session, track2)
    session.commit()
    track3_path = "/h/i/j"
    track3 = models.Tracks(session, track3_path)
    playlist_tab.insert_track(session, track3)
    session.commit()

    assert playlist_tab._get_current_track_row() is None
    assert playlist_tab._get_next_track_row() is None
    assert playlist_tab._get_notes_rows() == []
    assert playlist_tab._get_played_track_rows() == []
    assert len(playlist_tab._get_unreadable_track_rows()) == 3


def test_meta(qtbot, session):

    # Create playlist
    playlist = playlists.Playlists(session, "my playlist")
    playlist_tab = playlists.PlaylistTab(None, session, playlist.id)

    # Add some tracks
    track1_path = "/a/b/c"
    track1 = models.Tracks(session, track1_path)
    playlist_tab.insert_track(session, track1)
    session.commit()
    track2_path = "/d/e/f"
    track2 = models.Tracks(session, track2_path)
    playlist_tab.insert_track(session, track2)
    session.commit()
    track3_path = "/h/i/j"
    track3 = models.Tracks(session, track3_path)
    playlist_tab.insert_track(session, track3)
    session.commit()

    assert len(playlist_tab._get_unreadable_track_rows()) == 3

    assert playlist_tab._get_played_track_rows() == []
    assert playlist_tab._get_current_track_row() is None
    assert playlist_tab._get_next_track_row() is None
    assert playlist_tab._get_notes_rows() == []

    playlist_tab._set_played_row(0)
    assert playlist_tab._get_played_track_rows() == [0]
    assert playlist_tab._get_current_track_row() is None
    assert playlist_tab._get_next_track_row() is None
    assert playlist_tab._get_notes_rows() == []

    # Add a note
    note_text = "my note"
    note_row = 7    # will be added as row 3
    note = models.Notes(session, playlist.id, note_row, note_text)
    playlist_tab._insert_note(session, note)

    assert playlist_tab._get_played_track_rows() == [0]
    assert playlist_tab._get_current_track_row() is None
    assert playlist_tab._get_next_track_row() is None
    assert playlist_tab._get_notes_rows() == [3]

    playlist_tab._set_next_track_row(1)
    assert playlist_tab._get_played_track_rows() == [0]
    assert playlist_tab._get_current_track_row() is None
    assert playlist_tab._get_next_track_row() == 1
    assert playlist_tab._get_notes_rows() == [3]

    playlist_tab._set_current_track_row(2)
    assert playlist_tab._get_played_track_rows() == [0]
    assert playlist_tab._get_current_track_row() == 2
    assert playlist_tab._get_next_track_row() == 1
    assert playlist_tab._get_notes_rows() == [3]

    playlist_tab._clear_played_row_status(0)
    assert playlist_tab._get_played_track_rows() == []
    assert playlist_tab._get_current_track_row() == 2
    assert playlist_tab._get_next_track_row() == 1
    assert playlist_tab._get_notes_rows() == [3]

    playlist_tab._meta_clear_next()
    assert playlist_tab._get_played_track_rows() == []
    assert playlist_tab._get_current_track_row() == 2
    assert playlist_tab._get_next_track_row() is None
    assert playlist_tab._get_notes_rows() == [3]

    playlist_tab._clear_current_track_row()
    assert playlist_tab._get_played_track_rows() == []
    assert playlist_tab._get_current_track_row() is None
    assert playlist_tab._get_next_track_row() is None
    assert playlist_tab._get_notes_rows() == [3]

    # Test clearing again has no effect
    playlist_tab._clear_current_track_row()
    assert playlist_tab._get_played_track_rows() == []
    assert playlist_tab._get_current_track_row() is None
    assert playlist_tab._get_next_track_row() is None
    assert playlist_tab._get_notes_rows() == [3]


def test_clear_next(qtbot, session):
    # Create playlist
    playlist = models.Playlists(session, "my playlist")
    playlist_tab = playlists.PlaylistTab(None, session, playlist.id)

    # Add some tracks
    track1_path = "/a/b/c"
    track1 = models.Tracks(session, track1_path)
    playlist_tab.insert_track(session, track1)
    session.commit()
    track2_path = "/d/e/f"
    track2 = models.Tracks(session, track2_path)
    playlist_tab.insert_track(session, track2)
    session.commit()

    playlist_tab._set_next_track_row(1)
    assert playlist_tab._get_next_track_row() == 1

    playlist_tab.clear_next(session)
    assert playlist_tab._get_next_track_row() is None


def test_get_selected_row(qtbot, monkeypatch, session):

    monkeypatch.setattr(musicmuster, "Session", session)
    monkeypatch.setattr(playlists, "Session", session)

    # Create playlist and playlist_tab
    window = musicmuster.Window()
    playlist = models.Playlists(session, "test playlist")
    playlist_tab = playlists.PlaylistTab(window, session, playlist.id)

    # Add some tracks
    track1_path = "/a/b/c"
    track1 = models.Tracks(session, track1_path)
    playlist_tab.insert_track(session, track1)
    session.commit()
    track2_path = "/d/e/f"
    track2 = models.Tracks(session, track2_path)
    playlist_tab.insert_track(session, track2)
    session.commit()

    qtbot.addWidget(playlist_tab)
    with qtbot.waitExposed(window):
        window.show()
    row0_item0 = playlist_tab.item(0, 0)
    assert row0_item0 is not None
    rect = playlist_tab.visualItemRect(row0_item0)
    qtbot.mouseClick(
        playlist_tab.viewport(), Qt.LeftButton, pos=rect.center()
    )
    row_number = playlist_tab.get_selected_row()
    assert row_number == 0


def test_set_next(qtbot, monkeypatch, session):

    monkeypatch.setattr(musicmuster, "Session", session)
    monkeypatch.setattr(playlists, "Session", session)
    seed2tracks(session)

    playlist_name = "test playlist"
    # Create testing playlist
    window = musicmuster.Window()
    playlist = models.Playlists(session, playlist_name)
    playlist_tab = playlists.PlaylistTab(window, session, playlist.id)
    idx = window.tabPlaylist.addTab(playlist_tab, playlist_name)
    window.tabPlaylist.setCurrentIndex(idx)
    qtbot.addWidget(playlist_tab)

    # Add some tracks
    track1 = models.Tracks.get_by_filename(session, "isa.mp3")
    track1_title = track1.title
    assert track1_title

    playlist_tab.insert_track(session, track1)
    session.commit()
    track2 = models.Tracks.get_by_filename(session, "mom.mp3")
    playlist_tab.insert_track(session, track2)

    with qtbot.waitExposed(window):
        window.show()

    row0_item2 = playlist_tab.item(0, 2)
    assert row0_item2 is not None
    rect = playlist_tab.visualItemRect(row0_item2)
    qtbot.mouseClick(
        playlist_tab.viewport(), Qt.LeftButton, pos=rect.center()
    )
    selected_title = playlist_tab.get_selected_title()
    assert selected_title == track1_title

    qtbot.keyPress(playlist_tab.viewport(), "N",
                   modifier=Qt.ControlModifier)
    qtbot.wait(1000)


def test_kae(monkeypatch, session):
    # monkeypatch.setattr(dbconfig, "Session", session)
    monkeypatch.setattr(musicmuster, "Session", session)

    musicmuster.Window.kae()
    # monkeypatch.setattr(musicmuster, "Session", session)
    # monkeypatch.setattr(dbconfig, "Session", session)
    # monkeypatch.setattr(models, "Session", session)
    # monkeypatch.setattr(playlists, "Session", session)
