# Copyright 2019 LoveIsGrief
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
from quodlibet import plugins, qltk
from quodlibet.qltk.entry import UndoEntry
from quodlibet.util.thread import call_async_background, Cancellable

try:
    import musicbrainzngs
except ImportError as e:
    raise plugins.MissingModulePluginError("musicbrainzngs") from e

from gi.repository import Gtk
from quodlibet import _
from quodlibet.plugins import PluginConfig
from quodlibet.plugins.events import EventPlugin

ATTR_BRAINZ = "musicbrainz_trackid"
ATTR_RATING = "~#rating"

BRAINZ_APP = "quodlibetMusicBrainzSync"
VERSION = "0.1"

plugin_config = PluginConfig("musicbrainz-sync")
defaults = plugin_config.defaults
defaults.set("username", "")
defaults.set("password", "")


class MusicBrainzSyncPlugin(EventPlugin):
    PLUGIN_ID = "musicbrainzsync"
    VERSION = VERSION
    PLUGIN_NAME = _("MusicBrainz Sync")
    PLUGIN_DESC = _("Syncs the rating of a song with MusicBrainz.")

    def __init__(self):
        super().__init__()
        musicbrainzngs.set_rate_limit()
        musicbrainzngs.set_useragent(
            BRAINZ_APP, VERSION, "quodlibet@lists.sacredchao.net"
        )
        musicbrainzngs.auth(
            plugin_config.get("username"), plugin_config.get("password")
        )

    def plugin_on_changed(self, songs):
        ratings_dict = {
            song(ATTR_BRAINZ): int(song(ATTR_RATING) * 100)
            for song in songs
            if ATTR_BRAINZ in song and ATTR_RATING in song
        }
        if len(ratings_dict):
            call_async_background(
                musicbrainzngs.submit_ratings,
                Cancellable(),
                callback=lambda *args: (),
                kwargs={
                    "recording_ratings": ratings_dict,
                },
            )

    def PluginPreferences(self, parent):
        def changed(entry, key):
            if entry.get_property("sensitive"):
                plugin_config.set(key, entry.get_text())
                musicbrainzngs.auth(
                    plugin_config.get("username"), plugin_config.get("password")
                )

        box = Gtk.VBox(spacing=12)

        # first frame
        table = Gtk.Table(n_rows=5, n_columns=2)
        table.props.expand = False
        table.set_col_spacings(6)
        table.set_row_spacings(6)

        labels = []
        label_names = [_("User_name:"), _("_Password:")]
        for idx, name in enumerate(label_names):
            label = Gtk.Label(label=name)
            label.set_alignment(0.0, 0.5)
            label.set_use_underline(True)
            table.attach(
                label,
                0,
                1,
                idx,
                idx + 1,
                xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.SHRINK,
            )
            labels.append(label)

        row = 0

        # username
        entry = UndoEntry()
        entry.set_text(plugin_config.get("username"))
        entry.connect("changed", changed, "username")
        table.attach(entry, 1, 2, row, row + 1)
        labels[row].set_mnemonic_widget(entry)
        row += 1

        # password
        entry = UndoEntry()
        entry.set_text(plugin_config.get("password"))
        entry.set_visibility(False)
        entry.connect("changed", changed, "password")
        table.attach(entry, 1, 2, row, row + 1)
        labels[row].set_mnemonic_widget(entry)
        row += 1

        box.pack_start(qltk.Frame(_("Account"), child=table), True, True, 0)

        return box
