# info.py
#
# Copyright 2020-2024 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 typing import Optional

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

from .events import PageEvents
from .. import models
from ..config import FMT_DAY  # type:ignore # config is generated at compile time
from ..utils import clean_markup


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

    conf: Optional[models.Conference] = None
    win: Optional[Adw.ApplicationWindow] = None
    stack: Gtk.Stack = Gtk.Template.Child()  # type: ignore
    listbox: Gtk.ListBox = Gtk.Template.Child()  # type: ignore

    # 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: dict[str, models.Event] = {}
    _value: Optional[models.Event] = None

    def get_value(self):
        return self._value

    _model = ""

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

    @model.setter
    def model_setter(self, v):
        if v not in ["days", "tracks", "rooms"]:
            raise ValueError(f"Model {v} is not valid for PageList.")
        self._model = v

    def get_model(self):
        return self._model

    def __init__(self, win, conf, **kwargs):
        super().__init__(**kwargs)
        self.conf = conf
        self.win = win
        win.connect("conf-updated", self.update)
        self.update()

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

        # empty listbox
        self._widget_data = {}
        self.listbox.remove_all()

        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":
            if title == "":
                title = "- no track -"
            subtitle = ", ".join(str(r) for r in obj.room)

        row = Adw.ActionRow(
            activatable=True,
            selectable=False,
            title=clean_markup(title),
            subtitle=clean_markup(subtitle)
        )
        icon = Gtk.Image.new_from_icon_name('go-next-symbolic')
        row.add_suffix(icon)

        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()
        else:
            return 0, []

    @Gtk.Template.Callback()
    def on_litstbox_activated(self, listbox, row):
        self._value = value = self._widget_data[row]
        page = PageEvents(value, model=self._model)
        self.get_parent().push(page)

    def show_placeholder(self):
        self.stack.set_visible_child_name('list')
