"""
Timezone utilities for Terra-View.

Provides consistent timezone handling throughout the application.
All database times are stored in UTC; this module converts for display.
"""

from datetime import datetime
from zoneinfo import ZoneInfo
from typing import Optional

from backend.database import SessionLocal
from backend.models import UserPreferences


# Default timezone if none set
DEFAULT_TIMEZONE = "America/New_York"


def get_user_timezone() -> str:
    """
    Get the user's configured timezone from preferences.

    Returns:
        Timezone string (e.g., "America/New_York")
    """
    db = SessionLocal()
    try:
        prefs = db.query(UserPreferences).filter_by(id=1).first()
        if prefs and prefs.timezone:
            return prefs.timezone
        return DEFAULT_TIMEZONE
    finally:
        db.close()


def get_timezone_info(tz_name: str = None) -> ZoneInfo:
    """
    Get ZoneInfo object for the specified or user's timezone.

    Args:
        tz_name: Timezone name, or None to use user preference

    Returns:
        ZoneInfo object
    """
    if tz_name is None:
        tz_name = get_user_timezone()
    try:
        return ZoneInfo(tz_name)
    except Exception:
        return ZoneInfo(DEFAULT_TIMEZONE)


def utc_to_local(dt: datetime, tz_name: str = None) -> datetime:
    """
    Convert a UTC datetime to local timezone.

    Args:
        dt: Datetime in UTC (naive or aware)
        tz_name: Target timezone, or None to use user preference

    Returns:
        Datetime in local timezone
    """
    if dt is None:
        return None

    tz = get_timezone_info(tz_name)

    # Assume naive datetime is UTC
    if dt.tzinfo is None:
        dt = dt.replace(tzinfo=ZoneInfo("UTC"))

    return dt.astimezone(tz)


def local_to_utc(dt: datetime, tz_name: str = None) -> datetime:
    """
    Convert a local datetime to UTC.

    Args:
        dt: Datetime in local timezone (naive or aware)
        tz_name: Source timezone, or None to use user preference

    Returns:
        Datetime in UTC (naive, for database storage)
    """
    if dt is None:
        return None

    tz = get_timezone_info(tz_name)

    # Assume naive datetime is in local timezone
    if dt.tzinfo is None:
        dt = dt.replace(tzinfo=tz)

    # Convert to UTC and strip tzinfo for database storage
    return dt.astimezone(ZoneInfo("UTC")).replace(tzinfo=None)


def format_local_datetime(dt: datetime, fmt: str = "%Y-%m-%d %H:%M", tz_name: str = None) -> str:
    """
    Format a UTC datetime as local time string.

    Args:
        dt: Datetime in UTC
        fmt: strftime format string
        tz_name: Target timezone, or None to use user preference

    Returns:
        Formatted datetime string in local time
    """
    if dt is None:
        return "N/A"

    local_dt = utc_to_local(dt, tz_name)
    return local_dt.strftime(fmt)


def format_local_time(dt: datetime, tz_name: str = None) -> str:
    """
    Format a UTC datetime as local time (HH:MM format).

    Args:
        dt: Datetime in UTC
        tz_name: Target timezone

    Returns:
        Time string in HH:MM format
    """
    return format_local_datetime(dt, "%H:%M", tz_name)


def format_local_date(dt: datetime, tz_name: str = None) -> str:
    """
    Format a UTC datetime as local date (YYYY-MM-DD format).

    Args:
        dt: Datetime in UTC
        tz_name: Target timezone

    Returns:
        Date string
    """
    return format_local_datetime(dt, "%Y-%m-%d", tz_name)


def get_timezone_abbreviation(tz_name: str = None) -> str:
    """
    Get the abbreviation for a timezone (e.g., EST, EDT, PST).

    Args:
        tz_name: Timezone name, or None to use user preference

    Returns:
        Timezone abbreviation
    """
    tz = get_timezone_info(tz_name)
    now = datetime.now(tz)
    return now.strftime("%Z")


# Common US timezone choices for settings dropdown
TIMEZONE_CHOICES = [
    ("America/New_York", "Eastern Time (ET)"),
    ("America/Chicago", "Central Time (CT)"),
    ("America/Denver", "Mountain Time (MT)"),
    ("America/Los_Angeles", "Pacific Time (PT)"),
    ("America/Anchorage", "Alaska Time (AKT)"),
    ("Pacific/Honolulu", "Hawaii Time (HT)"),
    ("UTC", "UTC"),
]
