"""
Utility functions for formatting dates, times, and numbers
according to user preferences.
"""
from datetime import datetime, time, date
from zoneinfo import ZoneInfo

from django.utils import timezone


def convert_to_user_timezone(dt: datetime, user) -> datetime:
    """
    Convert a datetime to the user's effective timezone.

    :param dt: Datetime object to convert.
    :param user: User object with profile.
    :returns: Datetime in user's effective timezone.
    """
    if not hasattr(user, "profile"):
        return dt

    user_tz = ZoneInfo(user.profile.effective_timezone)
    if timezone.is_aware(dt):
        return dt.astimezone(user_tz)
    return dt.replace(tzinfo=ZoneInfo("UTC")).astimezone(user_tz)


def get_timezone_display(user) -> str:
    """
    Get the user's effective timezone name for display.

    :param user: User object with profile.
    :returns: Timezone name string.
    """
    if not hasattr(user, "profile"):
        return "UTC"
    return user.profile.effective_timezone


def format_date_for_user(d: date, user) -> str:
    """
    Format a date according to user's preferred format.

    :param d: Date or datetime object.
    :param user: User object with profile.
    :returns: Formatted date string.
    """
    if not hasattr(user, "profile"):
        return d.strftime("%Y-%m-%d")

    format_map = {
        "YYYY-MM-DD": "%Y-%m-%d",
        "DD/MM/YYYY": "%d/%m/%Y",
        "MM/DD/YYYY": "%m/%d/%Y",
        "DD.MM.YYYY": "%d.%m.%Y",
        "DD-MM-YYYY": "%d-%m-%Y",
    }
    python_format = format_map.get(user.profile.date_format, "%Y-%m-%d")
    return d.strftime(python_format)


def format_time_for_user(t: time, user) -> str:
    """
    Format a time according to user's 12/24-hour preference.

    :param t: Time or datetime object.
    :param user: User object with profile.
    :returns: Formatted time string.
    """
    if not hasattr(user, "profile"):
        return t.strftime("%H:%M")

    if user.profile.time_format == "12-hour":
        return t.strftime("%I:%M %p")
    return t.strftime("%H:%M")


def format_number_for_user(number, user) -> str:
    """
    Format a number with user's preferred thousand separator.

    :param number: Number to format (int or float).
    :param user: User object with profile.
    :returns: Formatted number string.
    """
    if not hasattr(user, "profile"):
        return f"{number:,}"

    separator = user.profile.thousand_separator
    formatted = f"{number:,}"

    if separator == "period":
        formatted = formatted.replace(",", ".")
    elif separator == "space":
        formatted = formatted.replace(",", "\u00a0")
    elif separator == "none":
        formatted = formatted.replace(",", "")

    return formatted


def get_effective_theme(user) -> str:
    """
    Resolve user's theme to a DaisyUI theme name.

    For 'auto' mode, returns the light theme name. JavaScript on the
    client side handles detecting system preference and switching to
    the dark theme if needed.

    :param user: User object with profile.
    :returns: DaisyUI theme name string.
    """
    if not hasattr(user, "profile"):
        return "corporate"

    profile = user.profile
    if profile.theme_mode == "dark":
        return profile.dark_theme_name
    return profile.theme_name
