"""Global daylight cycle preferences.

A single timezone applies to every daylight value source / color strip
source on the server, so it lives in the key/value settings table rather
than on each entity. The daylight streams read it on every wall-clock
sample (cheap dict lookup with a short cache window) so changing it in
the UI takes effect within ~1 second.
"""

from __future__ import annotations

import threading
import time

from ledgrab.utils import get_logger

logger = get_logger(__name__)

DAYLIGHT_TIMEZONE_KEY = "daylight_timezone"
_CACHE_TTL_SECONDS = 1.0

_lock = threading.Lock()
_cached_tz: str = ""
_cached_at: float = 0.0


def _read_from_db() -> str:
    """Read the persisted timezone from the settings table.

    Returns an empty string when unset, the table is unavailable, or
    the stored value is corrupt — empty means "use system local time".
    """
    try:
        from ledgrab.api.dependencies import get_database

        raw = get_database().get_setting(DAYLIGHT_TIMEZONE_KEY)
    except Exception as e:  # pragma: no cover — DB not initialised yet, e.g. in tests
        logger.debug("daylight timezone DB read failed: %s", e)
        return ""
    if not isinstance(raw, dict):
        return ""
    value = raw.get("value")
    return str(value) if isinstance(value, str) else ""


def get_daylight_timezone() -> str:
    """Return the configured global daylight timezone (cached briefly)."""
    global _cached_tz, _cached_at

    now = time.monotonic()
    with _lock:
        if now - _cached_at < _CACHE_TTL_SECONDS:
            return _cached_tz

    fresh = _read_from_db()
    with _lock:
        _cached_tz = fresh
        _cached_at = now
    return fresh


def set_daylight_timezone(tz: str | None) -> str:
    """Persist the global daylight timezone and refresh the cache.

    Returns the canonicalised stored value (empty string for None / blank).
    """
    canonical = str(tz or "").strip()
    try:
        from ledgrab.api.dependencies import get_database

        get_database().set_setting(DAYLIGHT_TIMEZONE_KEY, {"value": canonical})
    except Exception as e:
        logger.warning("Failed to persist daylight timezone: %s", e)

    global _cached_tz, _cached_at
    with _lock:
        _cached_tz = canonical
        _cached_at = time.monotonic()
    return canonical


def invalidate_cache() -> None:
    """Force the next ``get_daylight_timezone`` call to re-read from DB."""
    global _cached_at
    with _lock:
        _cached_at = 0.0
