# settings.py
#
# Copyright 2020-2025 Fabio Comuni, et al.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
from typing import Self, Optional
from enum import IntEnum

from gi.repository import Gio
from gi.repository import Gtk
from dateutil import tz


class UnitializedError(Exception):
    pass


# in secs
CACHE_NOCACHE = 0
CACHE_FIVE_MINUTES = 5 * 60
CACHE_ONE_HOUR = 60 * 60
CACHE_ONE_DAY = 24 * CACHE_ONE_HOUR
CACHE_ONE_WEEK = 7 * CACHE_ONE_DAY


class CacheDuration(IntEnum):
    NO_CACHE = 0
    FIVE_MINUTES = 1
    ONE_HOUR = 2
    ONE_DAY = 3
    ONE_WEEK = 4

    @classmethod
    def as_model(cls) -> Gtk.StringList:
        labels = [n.name.replace("_", " ").title() for n in cls]
        return Gtk.StringList.new(labels)

    @classmethod
    def get_duration(cls, enum_value):
        return [
            CACHE_NOCACHE,
            CACHE_FIVE_MINUTES,
            CACHE_ONE_HOUR,
            CACHE_ONE_DAY,
            CACHE_ONE_WEEK,
        ][enum_value]


class Settings(Gio.Settings):
    __gtype_name__ = "ConfySettings"
    _instance: Optional[Self] = None

    def __init__(self):
        """
            Init settings
        """
        Gio.Settings.__init__(self)

    @classmethod
    def instance(kls) -> Self:
        if kls._instance is None:
            raise UnitializedError("No instance. Settings has not intialized.")
        return kls._instance

    @classmethod
    def init(kls, app_id: str) -> Self:
        """
            Initialize and return a new Settings object
        """
        settings = Gio.Settings.new(app_id)
        settings.__class__ = kls
        kls._instance = settings
        return settings

    def get_list_cache(self) -> CacheDuration:
        return CacheDuration.get_duration(self.get_int('list-cache'))

    def get_event_cache(self) -> CacheDuration:
        return CacheDuration.get_duration(self.get_int('event-cache'))

    def get_timezone(self):
        return tz.tzlocal()

    def get_size(self) -> tuple[int, int]:
        return (self.get_int('window-width'), self.get_int('window-height'))

    def get_maximized(self) -> bool:
        return self.get_boolean('window-maximized')

    def set_size(self, size: tuple[int, int]):
        self.set_int('window-width', size[0])
        self.set_int('window-height', size[1])

    def set_maximized(self, maximized: bool):
        self.set_boolean('window-maximized', maximized)

