from gettext import gettext as _
from gi.repository import Gtk, GObject
from giara.constants import RESOURCE_PREFIX
from giara.ellipsized_label import make_ellipsized_label


class ChoicePickerPopover(Gtk.Popover):
    def __init__(self, relative_to, listbox, **kwargs):
        super().__init__(**kwargs)
        self.builder = Gtk.Builder.new_from_resource(
            f'{RESOURCE_PREFIX}/ui/choice_picker_popover_content.ui'
        )
        self.search_entry = self.builder.get_object('search_entry')
        self.relative_to = relative_to
        self.set_parent(self.relative_to)
        self.set_autohide(True)
        self.set_size_request(280, 400)
        self.sw = self.builder.get_object('scrolled_win')
        self.listbox = listbox
        self.listbox.get_style_context().remove_class('card')
        self.listbox.set_filter_func(self.filter_func, None, False)
        self.sw.set_child(self.listbox)
        self.search_entry.connect('changed', self.on_search_entry_changed)

        self.main_container = self.builder.get_object('main_container')
        self.set_child(self.main_container)
        self.listbox.connect('row-selected', lambda *args: self.popdown())

    def filter_func(self, row, data, notify_destroy):
        term = self.search_entry.get_text().strip().lower()
        if not term:
            return True
        return term in row.get_key().lower()

    def on_search_entry_changed(self, *args):
        self.listbox.invalidate_filter()

    def popup(self, *args):
        super().popup()
        self.main_container.show()


class ChoicePickerButton(Gtk.Button):
    __gsignals__ = {
        'changed': (
            GObject.SignalFlags.RUN_LAST,
            None,
            (Gtk.ListBoxRow,)
        )
    }

    def __init__(self, listbox, default_title=_('None')):
        super().__init__(hexpand=True)
        self.label = make_ellipsized_label(default_title)
        self.set_child(self.label)

        self.listbox = listbox
        self.popover = ChoicePickerPopover(self, self.listbox)
        self.connect('clicked', lambda *args: self.popover.popup())
        self.listbox.connect('row-selected', self.on_item_selected)

    def on_item_selected(self, listbox, row):
        self.emit('changed', row)
        self.label.set_text(row.title if row is not None else _('None'))

    def get_choice(self):
        return self.listbox.get_selected_row()
