# info.py
#
# Copyright 2020-2023 Fabio Comuni, et al.
#
# 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 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import Adw

from .. import models
from ..config import FMT_DAY
from ..utils import clean_markup
from ..widgets import EventActionRow


@Gtk.Template(resource_path="/net/kirgroup/confy/pages/list.ui")
class PageList(Gtk.Box):
    __gtype_name__ = "ConfyPageList"
    page_title = ""

    conf = None
    win = None
    stack = Gtk.Template.Child()
    listbox = Gtk.Template.Child()

    _update_handler_id = None
    # a quanto pare non posso attaccare nessun tipo di userdata a un ActionRow
    # quindi per sapere a quale oggetto si riferisce l'ActionRow attivato
    # mi tocca tenere un bel dizionario. E' brutto? Si. Frega qualcosa? Decisamente no.
    # La vecchia versione teneva la lista corrente degli oggetti, e ricavava il
    # selezionato da 'row.get_index()' nell' handler di 'row-activated'.
    # E' meglio o peggio? boh.
    _widget_data = {}
    _value = None

    def get_value(self):
        return self._value

    @GObject.Signal(name="row-activated")
    def row_activated(self):
        ...

    _model = ""
    @GObject.property(type=str, default="")
    def model(self):
        return self._model

    @model.setter
    def model(self, v):
        if self._update_handler_id:
            models.dbUpdateWatcher.disconnect(self._update_handler_id)
        _update_handler_id = None
        if v == "starred":
            self._update_handler_id = models.dbUpdateWatcher.connect("update", self.update)
        self._model = v

    def get_model(self):
        return self._model

    def init(self, win, conf):
        self.conf = conf
        self.win = win

        win.connect("conf-updated", self.update)
        return self

    def update(self, *_):
        count, data = self.get_objects()

        # empty listbox
        self._widget_data = {}
        w = self.listbox.get_last_child()
        while w:
            self.listbox.remove(w)
            w = self.listbox.get_last_child()

        if count == 0:
            self.show_placeholder()
        else:
            self.stack.set_visible_child_name('list')

        # fill listbox
        for idx, obj in enumerate(data):
            row = self.build_row(obj)
            self._widget_data[row] = obj
            self.listbox.append(row)

    def build_row(self, obj):
        """
        Return a widget for data in current listbox
        """

        title = str(obj)
        subtitle = ""
        if self._model == "days":
            title = obj.date.strftime(FMT_DAY)
        elif self._model == "tracks":
            subtitle = ", ".join(str(r) for r in obj.room)

        if self._model == "starred":
            row = EventActionRow(obj)
        else:
            row = Adw.ActionRow(
                activatable = True,
                selectable = False,
                title = clean_markup(title),
                subtitle = clean_markup(subtitle),
            )
            row.add_suffix(
                Gtk.Image.new_from_icon_name('go-next-symbolic')
            )

        return row

    def get_objects(self):
        if self._model == "days":
            return models.Day.count(), models.Day.all()
        elif self._model == "tracks":
            return models.Track.count(), models.Track.all()
        elif self._model == "rooms":
            return models.Room.count(), models.Room.all()
        elif self._model == "starred":
            g = models.Event.filter(starred=True)
            return next(g), g
        else:
            return 0, []

    @Gtk.Template.Callback()
    def on_litstbox_activated(self, listbox, row):
        self._value = self._widget_data[row]
        self.emit("row-activated")


    def show_placeholder(self):
        if self._model == "starred":
            self.stack.set_visible_child_name('empty_star')
        else:
            self.stack.set_visible_child_name('list')
