# -*- coding: utf-8 -*-
#  _____  ____   _               _
# |_   _|| __ ) | |  ___    ___ | | __
#   | |  |  _ \ | | / _ \  / __|| |/ /
#   | |  | |_) || || (_) || (__ |   <
#   |_|  |____/ |_| \___/  \___||_|\_\
#
# Copyright (C) 2021-2025 Camelia Lavender <camelia@tblock.me>

# 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 <https://www.gnu.org/licenses/>.

# Standard libraries
import sqlite3
from typing import AnyStr, Any
from enum import Enum

# External libraries
import requests
import tblock

# Local libraries
from .const import UPDATE_URL
from .version import __version__


class GUISettings(Enum):
    """
    Enum that represents different settings used by the GUI
    """

    LOGGING_ENABLED = "gui.logging.enabled"
    SETUP_COMPLETED = "gui.setup.completed"
    UPDATE_BETA = "gui.update.beta"
    UPDATE_STARTUP_CHECK = "gui.update.startup_check"


def get_setting(setting: AnyStr) -> bool:
    """
    Get the value of a setting
    :param setting: The setting to get
    :return: bool
    """
    try:
        with sqlite3.connect(tblock.Path.DATABASE) as _db:
            try:
                response = bool(
                    int(
                        _db.cursor()
                        .execute(
                            "SELECT value FROM system WHERE variable=?;", (setting,)
                        )
                        .fetchone()[0]
                    )
                )
            except TypeError:
                response = False
        return response
    except (FileNotFoundError, sqlite3.OperationalError):
        return False


def set_setting(setting: AnyStr, value: Any) -> None:
    """
    Set the value of a setting
    :param setting: The setting to change
    :param value: The value to use
    """
    with sqlite3.connect(tblock.Path.DATABASE) as _db:
        _cur = _db.cursor()
        response = _cur.execute(
            "SELECT value FROM system WHERE variable=?;", (setting,)
        ).fetchone()
        if response is None:
            _cur.execute(
                "INSERT INTO system (variable, value) VALUES (?, ?);", (setting, value)
            )
        else:
            _cur.execute(
                "UPDATE system SET value=? WHERE variable=?;", (value, setting)
            )


def update_available() -> bool:
    """
    Check if an update is available
    :return: bool
    """
    beta_channel = get_setting(GUISettings.UPDATE_BETA.value)
    try:
        if beta_channel:
            response = requests.get(UPDATE_URL["beta"], timeout=8)
        else:
            response = requests.get(UPDATE_URL["stable"], timeout=8)
    except (requests.ConnectTimeout, requests.ConnectionError):
        pass
    else:
        try:
            data = response.json()
            tag = data[0]["tag_name"]
            if tag > __version__:
                return True
            raise IndexError()
        except (IndexError, KeyError):
            pass
    return False
