# from gettext import gettext as _
from giara.constants import APP_ID
from pathlib import Path
from os.path import isfile
from os import environ as Env
from os import makedirs
import json
from gi.repository import GObject
from giara.singleton import Singleton
from giara.notification_manager import NotifManager


SCOPES = [
    'identity', 'history', 'mysubreddits', 'read', 'save', 'report', 'submit',
    'subscribe', 'vote', 'account', 'edit', 'livemanage', 'flair',
    'privatemessages'
]


class ConfManagerSignaler(GObject.Object):

    __gsignals__ = {
        'dark_mode_changed': (
            GObject.SignalFlags.RUN_FIRST,
            None,
            (str,)
        ),
        'on_show_thumbnails_in_preview_changed': (
            GObject.SignalFlags.RUN_FIRST,
            None,
            (str,)
        ),
        'notif_count_change': (
            GObject.SignalFlags.RUN_FIRST,
            None,
            (str,)
        ),
        'on_max_picture_height_changed': (
            GObject.SignalFlags.RUN_LAST,
            None,
            (str,)
        )
    }


class ConfManager(metaclass=Singleton):

    BASE_SCHEMA = {
        'windowsize': {
            'width': 350,
            'height': 650
        },
        'newentity_windowsize': {
            'width': 340,
            'height': 500
        },
        'dark_mode': False,
        'default_front_page_view': 'best',
        'refresh_token': '',
        'max_picture_height': 400,
        'show_thumbnails_in_preview': True,
        'twitter2nitter': False,
        'youtube2invidious': False,
        'invidious_instance': 'invidious.site',
        'nitter_instance': 'nitter.net',
        'blur_nsfw': True
    }

    def __init__(self):
        self.__reddit = None
        self.__application = None
        self.notifman = None
        self.signaler = ConfManagerSignaler()
        self.emit = self.signaler.emit
        self.connect = self.signaler.connect

        # check if inside flatpak sandbox
        self.is_flatpak = (
            'XDG_RUNTIME_DIR' in Env.keys() and
            isfile(f'{Env["XDG_RUNTIME_DIR"]}/flatpak-info')
        )

        if self.is_flatpak:
            self.path = Path(
                f'{Env.get("XDG_CONFIG_HOME")}/{APP_ID}.json'
            )
            self.cache_path = Path(
                f'{Env.get("XDG_CACHE_HOME")}/{APP_ID}'
            )
        else:
            self.path = Path(
                f'{Env.get("HOME")}/.config/{APP_ID}.json'
            )
            self.cache_path = Path(
                f'{Env.get("HOME")}/.cache/{APP_ID}'
            )
        self.thumbs_cache_path = self.cache_path.joinpath('thumbnails')
        self.network_cache_path = self.cache_path.joinpath('network')

        if self.path.is_file():
            try:
                with open(str(self.path)) as fd:
                    self.conf = json.loads(fd.read())
                # verify that the file has all of the schema keys
                for k in ConfManager.BASE_SCHEMA:
                    if k not in self.conf.keys():
                        if isinstance(
                                ConfManager.BASE_SCHEMA[k], (list, dict)
                        ):
                            self.conf[k] = ConfManager.BASE_SCHEMA[k].copy()
                        else:
                            self.conf[k] = ConfManager.BASE_SCHEMA[k]
            except Exception:
                self.conf = ConfManager.BASE_SCHEMA.copy()
                self.save_conf()
        else:
            self.conf = ConfManager.BASE_SCHEMA.copy()
            self.save_conf()

        if self.conf['default_front_page_view'] not in (
                'best', 'hot', 'new', 'top', 'rising', 'controversial'
        ):
            self.conf['default_front_page_view'] = 'best'
            self.save_conf()

        for p in (self.cache_path, self.thumbs_cache_path,
                  self.network_cache_path):
            if not p.is_dir():
                makedirs(str(p))

    def attempt_create_notifman(self):
        if (
                self.notifman is None and
                self.__reddit is not None and
                self.__application is not None
        ):
            self.notifman = NotifManager(
                self.__reddit,
                self.__application,
                self.emit
            )

    @property
    def reddit(self):
        if self.__reddit is None:
            raise AttributeError(
                'Attempting to access uninitialized reddit client instance'
            )
        else:
            return self.__reddit
            self.attempt_create_notifman()

    @reddit.setter
    def reddit(self, reddit):
        if self.__reddit is None:
            if reddit.auth.scopes() != set(SCOPES):
                raise ValueError(
                    "Current scopes don't match with the needed scopes"
                )
            else:
                self.__reddit = reddit
                self.reddit_user_me = self.__reddit.user.me()
                self.attempt_create_notifman()
        else:
            raise AttributeError(
                'Attempting to re-assing read only reddit client instance'
            )

    @property
    def application(self):
        if self.__application is None:
            raise AttributeError(
                'Attempting to access uninitialized application instance'
            )
        else:
            return self.__application
            self.attempt_create_notifman()

    @application.setter
    def application(self, application):
        if self.__application is None:
            self.__application = application
            self.attempt_create_notifman()
        else:
            raise AttributeError(
                'Attempting to re-assing read only application instance'
            )

    def save_conf(self, *args):
        with open(str(self.path), 'w') as fd:
            fd.write(json.dumps(self.conf))
