from giara.constants import RESOURCE_PREFIX
from giara.common_post_box import CommonPostBox
from giara.confManager import ConfManager
from gi.repository import Gtk, GLib
from threading import Thread


class PostPreview(CommonPostBox):
    def __init__(self, post, **kwargs):
        self.confman = ConfManager()
        super().__init__(
            post,
            Gtk.Builder.new_from_resource(
                f'{RESOURCE_PREFIX}/ui/post_preview.ui'
            ),
            **kwargs
        )
        self.get_style_context().add_class('card')
        self.get_style_context().add_class('activatable')

        def hide_show_image(*args):
            img_cont = self.builder.get_object('image_container')
            if self.confman.conf['show_thumbnails_in_preview']:
                img_cont.set_visible(True)
                if img_cont.get_child_at_index(0) is None:
                    self.set_post_image()
            else:
                img_cont.set_visible(False)

        self.confman.connect(
            'on_show_thumbnails_in_preview_changed',
            hide_show_image
        )

    def set_post_image(self):
        if self.confman.conf['show_thumbnails_in_preview']:
            super().set_post_image()


class PostPreviewListboxRow(Gtk.ListBoxRow):
    def __init__(self, post, **kwargs):
        super().__init__(**kwargs)
        self.post = post

        def lazy():
            self.post_preview = PostPreview(post)
            self.set_child(self.post_preview)
            self.show()

        GLib.idle_add(lazy, priority=GLib.PRIORITY_LOW)


class PostPreviewListbox(Gtk.ListBox):
    def __init__(self, post_gen_func, show_post_func, load_now=True, **kwargs):
        super().__init__(**kwargs)
        self.get_style_context().add_class('card-list')
        self.set_selection_mode(Gtk.SelectionMode.NONE)
        self.post_gen_func = post_gen_func
        self.show_post_func = show_post_func
        self.post_gen = None
        self.initialized = False
        self.loading = False
        if load_now:
            self.refresh()
        self.connect('row-activated', self.on_row_activate)

        self.stop_loading = False

    def set_gen_func(self, n_gen_func):
        self.post_gen_func = n_gen_func

    def empty(self, *args):
        while True:
            row = self.get_row_at_index(0)
            if row:
                self.remove(row)
            else:
                break

    def refresh(self, *args):
        self.initialized = True
        self.empty()
        self.post_gen = self.post_gen_func(limit=None)
        self.load_more()

    def _on_post_preview_row_loaded(self, target):
        row = PostPreviewListboxRow(target)
        self.append(row)

    def _async_create_post_preview_row(self, gen, num):
        for n in range(num):
            if self.stop_loading:
                break
            try:
                target = next(gen)
                GLib.idle_add(
                    self._on_post_preview_row_loaded, target,
                    priority=GLib.PRIORITY_LOW
                )
            except StopIteration:
                # TODO: add child indicating post stream end
                break
        self.loading = False

    def load_more(self, num=10):
        if not self.stop_loading and self.loading:
            return
        self.loading = True
        t = Thread(
            target=self._async_create_post_preview_row,
            args=(self.post_gen, num),
            daemon=True
        )
        self.stop_loading = False
        t.start()

    def on_row_activate(self, lb, row):
        if hasattr(row, 'post') and row.post is not None:
            self.show_post_func(row.post)
