from gi.repository import Gtk
from giara.post_preview import PostPreviewListbox
from giara.markdown_view import MarkdownView
from giara.subreddits_list_view import SubredditsListbox
from giara.confManager import ConfManager
from giara.giara_clamp import GiaraClamp


class SectionScrolledWindow(Gtk.ScrolledWindow):
    def __init__(self, post_preview_lbox, **kwargs):
        super().__init__(**kwargs)
        self.post_preview_lbox = post_preview_lbox
        self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        self.connect('edge_reached', self.on_edge_reached)

    def on_edge_reached(self, sw, pos):
        if len(self.post_preview_lbox.get_children()) < 10:
            return
        if pos == Gtk.PositionType.BOTTOM:
            self.post_preview_lbox.load_more()


class SectionsStack(Gtk.Stack):
    def __init__(self, sections: list, show_post_func,
                 show_subreddit_func=None, load_now=True, source=None,
                 **kwargs):
        super().__init__(**kwargs)
        self.confman = ConfManager()
        self.reddit = self.confman.reddit
        self.source = self.reddit.front if source is None else source
        self.sections = sections
        self.show_post_func = show_post_func
        self.show_subreddit_func = show_subreddit_func

        self.set_transition_type(Gtk.StackTransitionType.CROSSFADE)

        for section in self.sections:
            if (
                    'type' not in section.keys() or
                    section['type'] == 'post_preview'
            ):
                self.add_post_preview(section)
            elif section['type'] == 'text':
                self.add_text(section)
            elif section['type'] == 'links':
                self.add_links(section)
            elif section['type'] == 'subs':
                self.add_subreddit_listbox(section)
            else:
                raise ValueError(
                    'SectionsStack: unknown section type `{section["type"]}`'
                )

        self.show_all()

        self.connect('notify::visible-child', self.on_visible_child_change)
        if load_now:
            self.on_visible_child_change()

    def on_visible_child_change(self, *args):
        child = self.get_visible_child().get_child().get_child().get_child()
        gen_func = None
        if isinstance(child, SubredditsListbox):
            gen_func = child.subreddits_gen_func
        elif isinstance(child, PostPreviewListbox):
            gen_func = child.post_gen_func
        else:
            return
        if not child.initialized and gen_func is not None:
            child.refresh()

    def __make_clamp(self):
        clamp = GiaraClamp()
        return clamp

    def add_text(self, section):
        clamp = self.__make_clamp()
        markdown_view = MarkdownView(section['text'])
        markdown_view.get_style_context().add_class('card')
        markdown_view.get_style_context().add_class('padding12')
        clamp.add(markdown_view)
        sw = Gtk.ScrolledWindow()
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        sw.add(clamp)
        self.add_titled(
            sw,
            section['name'],
            section['title']
        )
        self.set_icon(section, sw)

    def add_links(self, section):
        clamp = self.__make_clamp()
        markdown_view = MarkdownView(
            '\n\n'.join(
                [f'[{lnk.label}]({lnk.url})' for lnk in section['links']])
        )
        clamp.add(markdown_view)
        sw = Gtk.ScrolledWindow()
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        sw.add(clamp)
        self.add_titled(
            sw,
            section['name'],
            section['title']
        )
        self.set_icon(section, sw)

    def add_subreddit_listbox(self, section):
        assert self.show_subreddit_func is not None, \
           'Show subreddit function cannot be None if you want to add a ' \
           'subreddit listbox'
        clamp = self.__make_clamp()
        subreddit_listbox = SubredditsListbox(
            section['gen'],
            self.show_subreddit_func,
            load_now=(
                'load_now' not in section.keys() or section['load_now']
            )
        )
        clamp.add(subreddit_listbox)
        sw = Gtk.ScrolledWindow()
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        sw.add(clamp)
        self.add_titled(
            sw,
            section['name'],
            section['title']
        )
        self.set_icon(section, sw)

    def add_post_preview(self, section):
        post_preview_clamp = self.__make_clamp()
        post_preview_lbox = PostPreviewListbox(
            section['gen'],
            self.show_post_func,
            load_now=False
        )
        post_preview_clamp.add(post_preview_lbox)
        sw = SectionScrolledWindow(post_preview_lbox)
        sw.add(post_preview_clamp)
        self.add_titled(
            sw,
            section['name'],
            section['title']
        )
        self.set_icon(section, sw)

    def set_icon(self, section, widget):
        if 'icon' in section.keys() and section['icon']:
            self.child_set_property(widget, 'icon-name', section['icon'])

    def refresh(self, *args):
        self.get_visible_child().post_preview_lbox.refresh()
