from datetime import datetime, date, timezone
import logging
from typing import Optional, Union
from zoneinfo import ZoneInfo

from django.utils.timezone import get_current_timezone

logger = logging.getLogger(__name__)


# ----------------------------------------------------------------------
def datetime_from_string(datestring: Union[datetime, str]) -> Optional[datetime]:
    """
    Get object from datetime or from string
    """
    if isinstance(datestring, datetime):
        return datestring

    try:
        return datetime.fromisoformat(datestring)
    except (TypeError, ValueError):
        return None


# ----------------------------------------------------------------------
def date_from_string(datestring: Union[datetime, str]) -> Optional[date]:
    """
    Convert date or datetime string to date object
    """
    dt = datetime_from_string(datestring) if isinstance(datestring, str) else datestring

    try:
        return dt.date() if dt else None
    except (AttributeError, ValueError):
        return None


# ----------------------------------------------------------------------
def tz_datetime_from_string(datestring: str, tz: ZoneInfo | None = None) -> Optional[datetime]:
    """
    Convert date string to date time
    Localize times, to handle ambiguous DST entries
    """
    # Any technique that we use here must be able to handle ambiguous
    # times like 2016-11-06 02:01:08
    dt = datetime_from_string(datestring) if isinstance(datestring, str) else datestring

    if isinstance(dt, str):
        return None

    try:
        return dt.astimezone(tz or get_current_timezone()) if dt else None
    except (AttributeError, ValueError):
        return None


# ----------------------------------------------------------------------
def as_local_tz(dt: datetime, tz: ZoneInfo | timezone | None = None) -> datetime:
    """
    Convert datetime to local timezone
    """
    try:
        return dt.astimezone(tz or get_current_timezone())
    except (AttributeError, ValueError):
        return dt


# ----------------------------------------------------------------------
weekdays = {
    'sun': {'name': 'Sunday', 'code': 'S', 'abbrev': 'Sun', 'num': 0},
    'mon': {'name': 'Monday', 'code': 'M', 'abbrev': 'Mon', 'num': 1},
    'tue': {'name': 'Tuesday', 'code': 'T', 'abbrev': 'Tue', 'num': 2},
    'wed': {'name': 'Wednesday', 'code': 'W', 'abbrev': 'Wed', 'num': 3},
    'thu': {'name': 'Thursday', 'code': 'H', 'abbrev': 'Thu', 'num': 4},
    'fri': {'name': 'Friday', 'code': 'F', 'abbrev': 'Fri', 'num': 5},
    'sat': {'name': 'Saturday', 'code': 'A', 'abbrev': 'Sat', 'num': 6},
}

__all__ = (
    'as_local_tz',
    'date_from_string',
    'datetime_from_string',
    'tz_datetime_from_string',
    'weekdays',
)
