from gettext import gettext as _
from gi.repository import Gtk, Pango
from gfeeds.confManager import ConfManager
from gfeeds.feeds_manager import FeedsManager
from gfeeds.initials_icon import InitialsIcon
from gfeeds.listbox_tools import separator_header_func


class FeedsViewAllListboxRow(Gtk.ListBoxRow):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.IS_ALL = True
        self.IS_TAG = False
        self.feed = None
        self.label = Gtk.Label()
        self.label.set_markup(
            '<b>' +
            _('All feeds') +
            '</b>'
        )
        self.label.set_use_markup(True)
        self.label.set_margin_top(12)
        self.label.set_margin_bottom(12)
        self.add(self.label)


class FeedsViewListboxRow(Gtk.ListBoxRow):
    def __init__(self, feed, description=True, **kwargs):
        super().__init__(**kwargs)
        self.confman = ConfManager()
        self.IS_ALL = False
        self.IS_TAG = False
        self.feed = feed
        self.title = feed.title
        self.builder = Gtk.Builder.new_from_resource(
            '/org/gabmus/gfeeds/ui/manage_feeds_listbox_row.glade'
        )
        self.hbox = self.builder.get_object('hbox')
        self.checkbox = self.builder.get_object('check')
        self.checkbox.set_no_show_all(True)
        self.checkbox.hide()

        self.icon_container = self.builder.get_object('icon_container')
        self.icon = InitialsIcon(
            self.feed.title,
            self.feed.favicon_path
        )
        self.icon_container.add(self.icon)

        self.name_label = self.builder.get_object('title_label')
        self.name_label.set_text(self.feed.title)
        self.confman.connect(
            'gfeeds_full_feed_name_changed',
            self.on_full_feed_name_changed
        )
        self.desc_label = self.builder.get_object('description_label')
        self.desc_label.set_no_show_all(not description)
        if description:
            self.desc_label.set_text(self.feed.description)
        else:
            self.desc_label.hide()
            self.name_label.set_ellipsize(Pango.EllipsizeMode.END)
        self.add(self.hbox)
        self.on_full_feed_name_changed()

    def on_full_feed_name_changed(self, *args):
        self.name_label.set_ellipsize(
            Pango.EllipsizeMode.NONE if self.confman.conf['full_feed_name']
            else Pango.EllipsizeMode.END
        )

    def __repr__(self):
        return f'<FeedsViewListboxRow - {self.title}>'


class FeedsViewTagListboxRow(Gtk.ListBoxRow):
    def __init__(self, tag, **kwargs):
        super().__init__(**kwargs)
        self.IS_TAG = True
        self.IS_ALL = False
        self.tag = tag
        self.title = tag
        self.feed = None
        self.builder = Gtk.Builder.new_from_resource(
            '/org/gabmus/gfeeds/ui/manage_feeds_listbox_row.glade'
        )
        self.hbox = self.builder.get_object('hbox')
        self.checkbox = self.builder.get_object('check')
        self.checkbox.set_no_show_all(True)
        self.checkbox.hide()
        self.icon_container = self.builder.get_object('icon_container')
        self.icon = Gtk.Image.new_from_icon_name(
            'tag-symbolic',
            Gtk.IconSize.INVALID
        )
        self.icon.set_pixel_size(32)
        self.icon_container.add(self.icon)

        self.name_label = self.builder.get_object('title_label')
        self.name_label.set_text(tag)
        self.desc_label = self.builder.get_object('description_label')
        self.desc_label.set_no_show_all(True)
        self.desc_label.hide()
        self.add(self.hbox)

    def __repr__(self):
        return f'<FeedsViewTagListboxRow - {self.title}>'


class FeedsViewListbox(Gtk.ListBox):
    def __init__(self, description=True, tags=False, **kwargs):
        super().__init__(**kwargs)
        self.description = description
        self.feedman = FeedsManager()
        self.confman = ConfManager()

        self.set_selection_mode(Gtk.SelectionMode.SINGLE)
        self.connect('row-activated', self.on_row_activated)

        for feed in self.feedman.feeds:
            self.add_feed(feed)
        self.feedman.feeds.connect(
            'empty',
            self.empty
        )
        self.feedman.feeds.connect(
            'append',
            self.on_feeds_append
        )
        self.feedman.feeds.connect(
            'pop',
            self.on_feeds_pop
        )

        if tags:
            self.confman.connect(
                'gfeeds_tags_append',
                self.on_tags_append
            )
            self.confman.connect(
                'gfeeds_tags_pop',
                self.on_tags_pop
            )

            for tag in self.confman.conf['tags']:
                self.on_tags_append(None, tag)

        self.set_sort_func(self.gfeeds_sort_func, None, False)
        self.set_header_func(separator_header_func)

    def on_feeds_pop(self, caller, feed):
        self.remove_feed(feed)

    def on_feeds_append(self, caller, feed):
        self.add_feed(feed)

    def on_tags_append(self, caller, tag):
        self.add(FeedsViewTagListboxRow(tag))

    def on_tags_pop(self, caller, tag):
        for row in self.get_children():
            if row.IS_TAG and row.tag == tag:
                self.remove(row)
                break

    def add_feed(self, feed):
        self.add(FeedsViewListboxRow(feed, self.description))

    def add(self, *args, **kwargs):
        super().add(*args, **kwargs)
        self.show_all()

    def on_row_activated(self, listbox, row):
        if row.IS_ALL:
            self.confman.emit('gfeeds_filter_changed', None)
            return
        if row.IS_TAG:
            self.confman.emit('gfeeds_filter_changed', [row.tag])
            return
        self.confman.emit('gfeeds_filter_changed', row.feed)

    def remove_feed(self, feed):
        for row in self.get_children():
            if not row.IS_ALL:
                if row.feed == feed:
                    self.remove(row)
                    break

    def empty(self, *args):
        rows = self.get_children()
        for row in rows:
            if row and not row.IS_ALL and not row.IS_TAG:
                self.remove(row)

    def row_all_activate(self, skip=False):
        if skip:
            return
        for row in self.get_children():
            if row.IS_ALL:
                row.activate()

    def gfeeds_sort_func(self, row1, row2, data, notify_destroy):
        if row1.IS_ALL:
            return False
        if row2.IS_ALL:
            return True
        if row1.IS_TAG and not row2.IS_TAG:
            return False
        if row2.IS_TAG and not row1.IS_TAG:
            return True
        return row1.title.lower() > row2.title.lower()


class FeedsViewScrolledWindow(Gtk.ScrolledWindow):
    def __init__(self, description=True, tags=False, **kwargs):
        super().__init__(**kwargs)
        self.listbox = FeedsViewListbox(description, tags)
        self.all_row = FeedsViewAllListboxRow()
        self.listbox.add(self.all_row)
        self.listbox.select_row(self.all_row)
        # self.set_size_request(360, 500)
        self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        self.add(self.listbox)
        self.set_size_request(250, 400)
        self.get_style_context().add_class('frame')
        self.set_margin_top(6)
        self.set_margin_end(6)
        self.set_margin_bottom(6)
        self.set_margin_start(6)


class FeedsViewPopover(Gtk.Popover):
    def __init__(self, relative_to, **kwargs):
        super().__init__(**kwargs)
        self.scrolled_win = FeedsViewScrolledWindow(
            description=False,
            tags=True
        )
        self.add(self.scrolled_win)
        self.set_modal(True)
        self.set_relative_to(relative_to)
        relative_to.connect('clicked', self.on_relative_to_clicked)

    def on_relative_to_clicked(self, *args):
        self.popup()
        self.show_all()
