"""Date formatting utilities with ordinal day numbers.

This module provides functions for formatting dates with ordinal day numbers
(1st, 2nd, 3rd, etc.) for natural language output. Used throughout Winston
for displaying dates in a screen reader-friendly format.

Functions convert datetime objects to formatted strings like:
- "Monday 15th January" (standard)
- "15th January" (short)
- "Monday 15th January 2025" (long)
- Current date as "Monday 15th January" (today)

Example:
    >>> import datetime
    >>> from winston.ordinal_date import ord_date
    >>> dt = datetime.datetime(2025, 1, 15)
    >>> ord_date(dt)
    'Wednesday 15th January'

Typical usage:
    from winston.ordinal_date import today
    print(f"Winston started on {today()}")
"""

from __future__ import annotations
import datetime
import inflect  # type: ignore[import]


def today() -> str:
    """Get current date formatted with ordinal day.

    Returns:
        Date string like "Monday 15th January".

    Example:
        >>> today()
        'Monday 15th January'
    """
    return ord_date(datetime.datetime.now())


def ord_day(dt_date: datetime.datetime) -> str:
    """Convert day number to ordinal string (1st, 2nd, 3rd, etc.).

    Args:
        dt_date: Datetime object to extract day from.

    Returns:
        Ordinal day string like "1st", "2nd", "3rd", "15th".

    Example:
        >>> import datetime
        >>> dt = datetime.datetime(2025, 1, 15)
        >>> ord_day(dt)
        '15th'
    """
    day = dt_date.day
    p = inflect.engine()
    return p.ordinal(day)  # type: ignore[arg-type]  # inflect accepts int despite Number | str type hint


def ord_date(dt_date: datetime.datetime) -> str:
    """Format date as "Weekday Nth Month" (e.g., "Monday 15th January").

    Args:
        dt_date: Datetime object to format.

    Returns:
        Date string with weekday, ordinal day, and month name.

    Example:
        >>> import datetime
        >>> dt = datetime.datetime(2025, 1, 15)
        >>> ord_date(dt)
        'Wednesday 15th January'
    """
    return dt_date.strftime("%A $day %B").replace('$day', ord_day(dt_date))


def ord_short_date(dt_date: datetime.datetime) -> str:
    """Format date as "Nth Month" without weekday (e.g., "15th January").

    Args:
        dt_date: Datetime object to format.

    Returns:
        Date string with ordinal day and month name only.

    Example:
        >>> import datetime
        >>> dt = datetime.datetime(2025, 1, 15)
        >>> ord_short_date(dt)
        '15th January'
    """
    return dt_date.strftime("$day %B").replace('$day', ord_day(dt_date))


def ord_long_date(dt_date: datetime.datetime) -> str:
    """Format date as "Weekday Nth Month Year" (e.g., "Monday 15th January 2025").

    Args:
        dt_date: Datetime object to format.

    Returns:
        Date string with weekday, ordinal day, month name, and year.

    Example:
        >>> import datetime
        >>> dt = datetime.datetime(2025, 1, 15)
        >>> ord_long_date(dt)
        'Wednesday 15th January 2025'
    """
    return dt_date.strftime("%A $day %B %Y").replace('$day', ord_day(dt_date))


if __name__ == '__main__':
    print(today())