from gi.repository import Gtk, Gdk, Gio
from giara.base_app import BaseApp, AppAction
from giara.constants import RESOURCE_PREFIX, APP_ID, APP_NAME
import sys
# import argparse
from gettext import gettext as _
# from os.path import isfile
from giara.confManager import ConfManager
from giara.app_window import AppWindow
from giara.preferences_window import PreferencesWindow
from giara.auth import (
    get_preauthorized_client,
    get_unauthorized_client,
    get_authorized_client,
    get_auth_link
)
from prawcore.exceptions import ResponseException
# import dbus


class GApplication(BaseApp):
    def __init__(self):
        super().__init__(
            app_id=APP_ID,
            app_name=APP_NAME,
            app_actions=[
                AppAction(
                    'settings', self.show_preferences_window,
                    '<Primary>comma'
                ),
                AppAction(
                    'shortcuts', self.show_shortcuts_window,
                    '<Primary>question'
                ),
                AppAction(
                    'about', self.show_about_dialog
                ),
                AppAction(
                    'quit', self.on_destroy_window,
                    '<Primary>q'
                ),
                AppAction(
                    'goinbox', self.go_inbox
                ),
                AppAction(
                    'go_subreddits', self.go_subreddits
                ),
                AppAction(
                    'go_multireddits', self.go_multireddits
                ),
                AppAction(
                    'go_profile', self.go_profile
                ),
                AppAction(
                    'go_saved', self.go_saved
                ),
                AppAction(
                    'go_logout', self.go_logout
                ),
                AppAction(
                    'r_all', self.go_r_all
                ),
                AppAction(
                    'r_popular', self.go_r_popular
                )
            ],
            flags=Gio.ApplicationFlags.HANDLES_OPEN,
            css_resource=f'{RESOURCE_PREFIX}/ui/gtk_style.css'
        )
        self.confman = ConfManager()
        self.confman.application = self
        self._unauth_reddit = get_unauthorized_client()
        self.reddit = None
        self.login_window = None
        self.connect('open', self.open)

    def open(self, app, files, *args):
        target = files[0].get_uri()
        print(target)
        code = target.split('=')[-1].split('#')[0]
        get_authorized_client(
            reddit=self._unauth_reddit, code=code
        )
        self.continue_activate(self._unauth_reddit)

    def quit(self, *args, **kwargs):
        if self.confman.notifman is not None:
            self.confman.notifman.stop()
        super().quit(*args, **kwargs)

    def go_inbox(self, *args):
        self.window.main_ui.deck.left_stack.on_go_inbox()

    def go_subreddits(self, *args):
        self.window.main_ui.deck.left_stack.on_go_subreddits_list()

    def go_multireddits(self, *args):
        self.window.main_ui.deck.left_stack.on_go_multireddits_list()

    def go_profile(self, *args):
        self.window.main_ui.deck.left_stack.on_go_profile()

    def go_saved(self, *args):
        self.window.main_ui.deck.left_stack.on_go_saved()

    def go_logout(self, *args):
        dialog = Gtk.MessageDialog(
            transient_for=self.window,
            modal=True,
            message_type=Gtk.MessageType.QUESTION,
            buttons=Gtk.ButtonsType.YES_NO,
            text=_('Do you want to log out? This will close the application.'),
            use_markup=True
        )

        def on_response(dialog, res):
            dialog.close()
            if res == Gtk.ResponseType.YES:
                self.confman.conf['refresh_token'] = ''
                self.confman.save_conf()
                self.window.close()

        dialog.connect('response', on_response)
        dialog.present()
        dialog.show()

    def go_r_all(self, *args):
        self.window.main_ui.deck.left_stack.on_go_r_all()

    def go_r_popular(self, *args):
        self.window.main_ui.deck.left_stack.on_go_r_popular()

    def show_about_dialog(self, *args):
        about_builder = Gtk.Builder.new_from_resource(
            f'{RESOURCE_PREFIX}/aboutdialog.ui'
        )
        dialog = about_builder.get_object('aboutdialog')
        dialog.set_modal(True)
        dialog.set_transient_for(self.window)
        dialog.present()

    def on_destroy_window(self, *args):
        if self.window:
            self.window.on_destroy()
        self.quit()

    def show_shortcuts_window(self, *args):
        shortcuts_win = Gtk.Builder.new_from_resource(
            f'{RESOURCE_PREFIX}/ui/shortcutsWindow.ui'
        ).get_object('shortcuts-win')
        shortcuts_win.props.section_name = 'shortcuts'
        shortcuts_win.set_transient_for(self.window)
        shortcuts_win.set_modal(True)
        shortcuts_win.present()

    def show_preferences_window(self, *args):
        preferences_win = PreferencesWindow(self.window)
        preferences_win.present()

    def create_login_win(self, login_url: str):
        builder = Gtk.Builder.new_from_resource(
            f'{RESOURCE_PREFIX}/ui/login_view.ui'
        )
        self.login_window = builder.get_object('login_window')
        self.login_window.set_default_size(350, 500)

        def on_login_win_destroy(*args):
            if self.reddit is None:
                self.quit()
                sys.exit(0)

        self.login_window.connect(
            'destroy',
            on_login_win_destroy
        )
        builder.get_object('copy_login_link_btn').connect(
            'clicked',
            lambda *args: Gdk.Display.get_default().get_clipboard().set(
                login_url
            )
        )

        def on_login_clicked(*args):
            builder.get_object('stack').set_visible_child(
                builder.get_object('waiting_box')
            )
            # try:
            #     bus = dbus.SessionBus()
            #     d = bus.get_object(
            #         'org.freedesktop.portal.Desktop',
            #         '/org/freedesktop/portal/desktop'
            #     )
            #     iface = dbus.Interface(
            #         d, dbus_interface='org.freedesktop.portal.OpenURI'
            #     )
            #     iface.OpenURI(None, login_url)
            # except Exception:
            Gio.AppInfo.launch_default_for_uri(
                login_url
            )

        builder.get_object('login_btn').connect(
            'clicked',
            on_login_clicked
        )

    def do_activate(self):
        super().do_activate()
        self.get_reddit_client()

    def get_reddit_client(self, refresh_token=None):
        if refresh_token is None:
            refresh_token = self.confman.conf['refresh_token']
        if refresh_token != '':
            try:
                return self.continue_activate(
                    get_preauthorized_client(refresh_token)
                )
            except ResponseException:
                return self.get_reddit_client('')
            except ValueError as e:
                if 'scope' in repr(e).lower():
                    return self.get_reddit_client('')
        else:
            self.confman.conf['refresh_token'] = ''
            # self._unauth_reddit = get_unauthorized_client()  # moved up
            self.create_login_win(get_auth_link(self._unauth_reddit))
            assert(self.login_window is not None)
            self.add_window(self.login_window)
            self.login_window.present()
            self.login_window.show()

    def continue_activate(self, reddit=None):
        if reddit is None:
            self.reddit = self.confman.reddit
        else:
            self.reddit = reddit
            self.confman.reddit = reddit
        if self.login_window is not None:
            self.login_window.destroy()
        self.window = AppWindow()
        self.window.connect('close-request', self.on_destroy_window)
        self.add_window(self.window)
        self.window.present()
        self.window.show()
        if hasattr(self, 'args'):
            if self.args:
                pass
        self.window.do_startup()

    def do_command_line(self, args):
        """
        GTK.Application command line handler
        called if Gio.ApplicationFlags.HANDLES_COMMAND_LINE is set.
        must call the self.do_activate() to get the application up and running.
        """
        # call the default commandline handler
        Gtk.Application.do_command_line(self, args)
        # make a command line parser
        #  #parser = argparse.ArgumentParser()
        #  #parser.add_argument(
        #  #    'argurl',
        #  #    metavar=_('url'),
        #  #    type=str,
        #  #    nargs='?',
        #  #    help=_('opml file local url or rss remote url to import')
        #  #)
        # parse the command line stored in args,
        # but skip the first element (the filename)
        #  #self.args = parser.parse_args(args.get_arguments()[1:])
        # call the main program do_activate() to start up the app
        self.do_activate()
        return 0


def main():
    application = GApplication()

    try:
        ret = application.run(sys.argv)
    except SystemExit as e:
        ret = e.code

    sys.exit(ret)


if __name__ == '__main__':
    main()
