from gettext import gettext as _
from gi.repository import Gtk, Adw
from giara.sections import PostListSection
from giara.front_page_headerbar import FrontPageHeaderbar
from giara.single_post_stream_view import SinglePostStreamView
from giara.subreddits_list_view import SubredditsListView
from giara.subreddit_view import SubredditView
from giara.search_view import SearchView
from giara.user_view import UserView
from giara.confManager import ConfManager
from giara.subreddit_search_view import SubredditSearchView
from giara.accel_manager import add_mouse_button_accel
from praw.models import Redditor
from giara.multireddit_list_view import MultiredditsListView
from giara.multireddit_view import MultiredditView
from giara.inbox_view import InboxListView


class LeftStack(Adw.Bin):
    def __init__(self, show_post_func):
        super().__init__()
        self._view_stack = Gtk.Stack(
            transition_type=Gtk.StackTransitionType.CROSSFADE
        )
        self.set_child(self._view_stack)
        self.add_titled = self._view_stack.add_titled
        self.set_visible_child = self._view_stack.set_visible_child
        self.remove = self._view_stack.remove

        self.confman = ConfManager()
        self.reddit = self.confman.reddit
        self.user_me = self.reddit.user.me()
        self.show_post_func = show_post_func

        # Child 1: Front page stack and respective headerbar
        self.front_page_view = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        front_generator = getattr(
            self.reddit.front,
            self.confman.conf['default_front_page_view']
        )
        self.front_page_section = PostListSection(
            front_generator, show_post_func,
            load_now=False, source=self.reddit.front
        )
        self.front_page_headerbar = FrontPageHeaderbar(
            self.front_page_section
        )
        self.front_page_view.headerbar = self.front_page_headerbar
        self.front_page_view.append(self.front_page_headerbar)
        self.front_page_headerbar.refresh_btn.connect(
            'clicked',
            self.front_page_section.refresh
        )
        self.front_page_view.append(self.front_page_section)
        self.front_page_headerbar.connect(
            'squeeze',
            lambda caller, squeezed: self.front_page_bottom_bar.set_reveal(
                squeezed
            )
        )
        self.add_titled(
            self.front_page_view,
            'front_page',
            _('Front page')
        )

        # Child 2: Saved items stack (forcedly a stack to preserve structure)
        self.saved_view = SinglePostStreamView(
            self.user_me.saved,
            'saved',
            _('Saved posts'),
            show_post_func,
            sort_menu=False,
            load_now=False
        )
        self.add_titled(
            self.saved_view,
            'saved_view',
            _('Saved posts')
        )

        # Child 3: Profile view
        self.profile_view = SinglePostStreamView(
            self.user_me.new,
            'profile',
            _('Profile'),
            show_post_func,
            load_now=False,
            sort_menu=False
        )
        self.add_titled(
            self.profile_view,
            'profile_view',
            _('Profile')
        )

        # Child 4: Subreddits list view
        self.subreddits_list_view = SubredditsListView(
            lambda *args, **kwargs: self.reddit.user.subreddits(
                *args, **kwargs
            ),
            self.show_subreddit_func, sort=True, load_now=False
        )
        self.add_titled(
            self.subreddits_list_view,
            'subreddits',
            _('Subreddits')
        )

        # Child 5: Single subreddit view, initialized in show_subreddit_func
        self.single_subreddit_view = None
        # Child 6: Single subreddit search view
        # closely related to 5, created along 5
        self.single_subreddit_search_view = None

        # Child 7: Search view
        self.search_view = SearchView(
            show_post_func,
            lambda *args, **kwargs: self.show_subreddit_func(
                *args, **kwargs, prev_view=self.search_view
            )
        )
        self.add_titled(
            self.search_view,
            'search',
            _('Search')
        )

        def on_go_search(*args):
            self.set_visible_child(self.search_view)
            self.search_view.searchbar.set_search_mode(True)

        self.front_page_view.headerbar.search_btn.connect(
            'clicked', on_go_search
        )

        # Child 8: Inbox view
        self.inbox_view = InboxListView(
            self.reddit.inbox.all,
            show_post_func,
            load_now=False
        )
        self.add_titled(
            self.inbox_view,
            'inbox_view',
            _('Inbox')
        )

        # Child 9: Multireddits list view
        self.multireddits_list_view = MultiredditsListView(
            self.show_multireddit_func, load_now=False
        )
        self.add_titled(
            self.multireddits_list_view,
            'multireddits',
            _('Multireddits')
        )

        # Child 10: Single multireddit view,
        # initialized in show_multireddit_func
        self.single_multireddit_view = None

        # Child 11: r/all view
        r_all_sub = self.confman.reddit.subreddit('all')
        self.r_all_view = SinglePostStreamView(
            r_all_sub.hot,
            'r_all', _('r/all'), show_post_func, load_now=False,
            source=r_all_sub, sort_menu=True
        )
        self.add_titled(
            self.r_all_view,
            'r_all',
            _('r/all')
        )

        # Child 12: r/popular view
        r_popular_sub = self.confman.reddit.subreddit('popular')
        self.r_popular_view = SinglePostStreamView(
            r_popular_sub.hot,
            'r_popular', _('r/popular'), show_post_func, load_now=False,
            source=r_popular_sub, sort_menu=True
        )
        self.add_titled(
            self.r_popular_view,
            'r_popular',
            _('r/popular')
        )

        for view in (
                self.saved_view, self.profile_view, self.subreddits_list_view,
                self.search_view, self.inbox_view, self.multireddits_list_view,
                self.r_all_view, self.r_popular_view
        ):

            def go_back(*args):
                self.set_visible_child(self.front_page_view)

            def on_mouse_event(gesture, n_press, x, y):
                if gesture.get_current_button() == 8:  # Mouse back btn
                    go_back()

            view.headerbar.back_btn.connect('clicked', go_back)
            # the mouse accelerator needs to be kept around, thus this useless
            # assignment
            view.mouse_btn_accel = add_mouse_button_accel(
                view, on_mouse_event
            )

    def on_go_subreddits_list(self, *args):
        self.set_visible_child(self.subreddits_list_view)
        self.subreddits_list_view.first_refresh()

    def on_go_multireddits_list(self, *args):
        self.set_visible_child(self.multireddits_list_view)
        self.multireddits_list_view.first_refresh()

    def on_go_profile(self, *args):
        self.set_visible_child(self.profile_view)
        self.profile_view.first_refresh()

    def on_go_saved(self, *args):
        self.set_visible_child(self.saved_view)
        self.saved_view.refresh()

    def on_go_inbox(self, *args):
        self.set_visible_child(self.inbox_view)
        self.inbox_view.listbox.refresh()

    def on_go_r_all(self, *args):
        self.set_visible_child(self.r_all_view)
        self.r_all_view.first_refresh()

    def on_go_r_popular(self, *args):
        self.set_visible_child(self.r_popular_view)
        self.r_popular_view.first_refresh()

    def get_headerbar(self):
        return self.get_visible_child().headerbar

    def show_multireddit_func(self, multi):
        if self.single_multireddit_view is not None:
            self.remove(self.single_multireddit_view)
        self.single_multireddit_view = MultiredditView(
            multi, self.show_post_func
        )

        self.add_titled(
            self.single_multireddit_view,
            multi.display_name,
            multi.display_name
        )

        def back_to_prev(*args):
            self.set_visible_child(self.multireddits_list_view)

        def on_mouse_event(gesture, n_press, x, y):
            if gesture.get_current_button() == 8:  # Mouse back btn
                back_to_prev()

        self.single_multireddit_view.headerbar.back_btn.connect(
            'clicked', back_to_prev
        )
        self.single_multireddit_view.mouse_btn_accel = add_mouse_button_accel(
            self.single_multireddit_view, on_mouse_event
        )

        self.single_multireddit_view.show()
        self.set_visible_child(self.single_multireddit_view)

    def show_subreddit_func(self, sub, prev_view=None):

        def back_to_sub(*args):
            self.set_visible_child(self.single_subreddit_view)

        def on_mouse_event(gesture, n_press, x, y):
            if gesture.get_current_button() == 8:  # Mouse back btn
                back_to_sub()

        if prev_view is None:
            prev_view = self.subreddits_list_view
        for view in (
                self.single_subreddit_view,
                self.single_subreddit_search_view
        ):
            if view is not None:
                self.remove(view)
        if isinstance(sub, Redditor) or '/user/' in sub.url:
            redditor = sub
            if not isinstance(sub, Redditor):
                redditor = self.reddit.redditor(
                    sub.display_name_prefixed.replace('u/', '')
                )
            self.single_subreddit_view = UserView(
                redditor,
                self.show_post_func
            )
        else:
            self.single_subreddit_view = SubredditView(
                sub, self.show_post_func
            )
            self.single_subreddit_search_view = SubredditSearchView(
                sub, self.show_post_func
            )

            self.single_subreddit_search_view.headerbar.back_btn.connect(
                'clicked', back_to_sub
            )
            self.single_subreddit_search_view.mouse_btn_accel = \
                add_mouse_button_accel(
                    self.single_subreddit_search_view, on_mouse_event
                )

            def show_search():
                self.single_subreddit_search_view.show()
                self.set_visible_child(
                    self.single_subreddit_search_view
                )

            self.single_subreddit_view.headerbar.search_btn.connect(
                'clicked', lambda *args: show_search()
            )
            self.add_titled(
                self.single_subreddit_search_view,
                f'search_{sub.display_name}',
                _('Searching in {0}').format(sub.display_name_prefixed)
            )

        self.add_titled(
            self.single_subreddit_view,
            'sub_view',
            sub.display_name_prefixed
        )
        self.single_subreddit_view.add_heading()

        def back_to_prev(*args):
            self.set_visible_child(prev_view)

        def on_mouse_event_prev(gesture, n_press, x, y):
            if gesture.get_current_button() == 8:  # Mouse back btn
                back_to_prev()

        self.single_subreddit_view.headerbar.back_btn.connect(
            'clicked', back_to_prev
        )
        self.single_subreddit_view.mouse_btn_accel = add_mouse_button_accel(
            self.single_subreddit_view, on_mouse_event_prev
        )

        self.single_subreddit_view.show()
        self.set_visible_child(self.single_subreddit_view)
