from typing import List, Any

from .. import util
from ..common import IconButton, IconToggleButton, SpinnerImage, SpinnerPicture
from .manager import Manager
from ...util import resolve_path

from gi.repository import Gdk, GdkPixbuf, GLib, GObject, Gtk, Pango, Handy

def create_play_button(manager: Manager, large=True, **kwargs):
    button = IconButton(
        "media-playback-start-symbolic",
        "Play",
        relief=large,
        icon_size=Gtk.IconSize.LARGE_TOOLBAR,
        **kwargs,
    )

    if large:
        button.get_style_context().add_class("play-button-large")

    button.set_action_name("app.play-pause")
    manager.bind_property("has-song", button, "sensitive")
    manager.bind_property("play-button-icon", button, "icon-name")
    manager.bind_property("play-button-tooltip", button, "tooltip-text")

    return button

def create_repeat_button(manager: Manager, **kwargs):
    button = IconToggleButton("media-playlist-repeat", "Switch between repeat modes", **kwargs)
    button.set_action_name("app.repeat-press")
    manager.bind_property("repeat-button-icon", button, "icon-name")

    def on_active_change(*_):
        if manager.repeat_button_active != button.get_active():
            # Don't run the action, just update visual state
            button.set_action_name(None)
            button.set_active(manager.repeat_button_active)
            button.set_action_name("app.repeat-press")
    manager.connect("notify::repeat-button-active", on_active_change)

    return button

def create_shuffle_button(manager: Manager, **kwargs):
    button = IconToggleButton("media-playlist-shuffle-symbolic", "Toggle playlist shuffling", **kwargs)
    button.set_action_name("app.shuffle-press")

    def on_active_change(*_):
        if manager.shuffle_button_active != button.get_active():
            # Don't run the action, just update visual state
            button.set_action_name(None)
            button.set_active(manager.shuffle_button_active)
            button.set_action_name("app.shuffle-press")
    manager.connect("notify::shuffle-button-active", on_active_change)

    return button

def create_next_button(manager: Manager, **kwargs):
    button = IconButton(
        "media-skip-forward-symbolic",
        "Go to next song",
        icon_size=Gtk.IconSize.LARGE_TOOLBAR,
        **kwargs,
    )
    button.set_action_name("app.next-track")
    manager.bind_property("has-song", button, "sensitive")

    return button

def create_prev_button(manager: Manager, **kwargs):
    button = IconButton(
        "media-skip-backward-symbolic",
            "Go to previous song",
        icon_size=Gtk.IconSize.LARGE_TOOLBAR,
        **kwargs,
    )
    button.set_action_name("app.prev-track")
    manager.bind_property("has-song", button, "sensitive")

    return button

def create_label(manager: Manager, property: str, **kwargs):
    label = Gtk.Label(**kwargs)
    manager.bind_property(property, label, "label")
    return label

def show_play_queue_popover(manager: Manager, relative_to, paths: List[str], pos_x: int, pos_y: int):
    song_ids = [manager.play_queue_store[p][-1] for p in paths]

    remove_text = (
        "Remove " + util.pluralize("song", len(song_ids)) + " from queue"
    )

    def on_download_state_change(song_id: str):
        # Refresh the entire window (no force) because the song could
        # be in a list anywhere in the window.
        manager.emit("refresh-window", {}, False)

    def on_remove_songs_click(_: Any):
        manager.emit("songs-removed", [p.get_indices()[0] for p in paths])

    util.show_song_popover(
        song_ids,
        pos_x,
        pos_y,
        relative_to,
        manager.offline_mode,
        on_download_state_change=on_download_state_change,
        extra_menu_items=[
            (Gtk.ModelButton(text=remove_text), on_remove_songs_click),
        ],
    )

# Album Art column. This function defines what image to use for the play queue
# song icon.
def filename_to_pixbuf(
    column: Any,
    cell: Gtk.CellRendererPixbuf,
    model: Gtk.ListStore,
    tree_iter: Gtk.TreeIter,
    flags: Any,
):
    cell.set_property("sensitive", model.get_value(tree_iter, 0))
    filename = model.get_value(tree_iter, 1)
    if not filename:
        cell.set_property("icon_name", "")
        return

    pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(filename, 50, 50, True)

    # If this is the playing song, then overlay the play icon.
    if model.get_value(tree_iter, 3):
        play_overlay_pixbuf = GdkPixbuf.Pixbuf.new_from_file(
            str(resolve_path("ui/images/play-queue-play.png"))
        )

        play_overlay_pixbuf.composite(
            pixbuf, 0, 0, 50, 50, 0, 0, 1, 1, GdkPixbuf.InterpType.NEAREST, 200
        )

    cell.set_property("pixbuf", pixbuf)
