"""
core/tz.py - Timezone-aware date/time helpers

The frontend sends:
  X-Timezone-Name   – IANA timezone (e.g. "America/Chicago"), preferred
  X-Timezone-Offset – minutes from UTC (JS getTimezoneOffset sign), fallback

For background tasks (no request context) the scheduler reads the stored
timezone_name / timezone_offset from user_preferences.
"""

from datetime import datetime, date, timezone, timedelta
from zoneinfo import ZoneInfo

import core.postgres as postgres

# ── Request-context helpers (used by Flask route handlers) ────────────

def _get_request_tz():
    """Return a tzinfo from the current Flask request headers.
    Prefers X-Timezone-Name (IANA), falls back to X-Timezone-Offset."""
    try:
        import flask
        name = flask.request.headers.get("X-Timezone-Name")
        if name:
            try:
                return ZoneInfo(name)
            except (KeyError, Exception):
                pass
        offset = int(flask.request.headers.get("X-Timezone-Offset", 0))
        return timezone(timedelta(minutes=-offset))
    except (ValueError, TypeError, RuntimeError):
        return timezone.utc


def _get_offset_minutes():
    """Read the timezone offset header from the current Flask request.
    Returns 0 if outside a request context or header is absent."""
    try:
        import flask
        return int(flask.request.headers.get("X-Timezone-Offset", 0))
    except (ValueError, TypeError, RuntimeError):
        return 0


def _offset_to_tz(offset_minutes):
    """Convert JS-style offset (positive = behind UTC) to a timezone object."""
    return timezone(timedelta(minutes=-offset_minutes))


def user_now(offset_minutes=None):
    """Current datetime in the user's timezone (request-context).
    If offset_minutes is provided, uses that directly.
    Otherwise reads request headers (prefers IANA name over offset)."""
    if offset_minutes is not None:
        tz = _offset_to_tz(offset_minutes)
    else:
        tz = _get_request_tz()
    return datetime.now(tz)


def user_today(offset_minutes=None):
    """Current date in the user's timezone."""
    return user_now(offset_minutes).date()


# ── Stored-preference helpers (used by scheduler / background jobs) ───

def tz_for_user(user_uuid):
    """Return a tzinfo for *user_uuid* from stored preferences.
    Priority: timezone_name (IANA) > timezone_offset (minutes) > UTC."""
    prefs = postgres.select_one("user_preferences", {"user_uuid": user_uuid})
    if prefs:
        name = prefs.get("timezone_name")
        if name:
            try:
                return ZoneInfo(name)
            except (KeyError, Exception):
                pass
        offset = prefs.get("timezone_offset")
        if offset is not None:
            return timezone(timedelta(minutes=-offset))
    return timezone.utc


def user_now_for(user_uuid):
    """Current datetime in a user's timezone using their stored preferences."""
    return datetime.now(tz_for_user(user_uuid))


def user_today_for(user_uuid):
    """Current date in a user's timezone using their stored preferences."""
    return user_now_for(user_uuid).date()
