"""Date and time utility tools."""

from datetime import datetime, timedelta

from pydantic_ai.toolsets import FunctionToolset

datetime_toolset: FunctionToolset[None] = FunctionToolset()


@datetime_toolset.tool
def get_current_time(
    timezone: str = "UTC",
) -> str:
    """Get the current date and time.

    Args:
        timezone: Timezone name (currently only UTC supported).
    """
    now = datetime.utcnow()
    return f"Current time ({timezone}): {now.strftime('%Y-%m-%d %H:%M:%S')}"


@datetime_toolset.tool
def parse_date(
    date_string: str,
    format_string: str = "%Y-%m-%d",
) -> str:
    """Parse a date string into a standard format.

    Args:
        date_string: The date string to parse.
        format_string: Expected format (default: YYYY-MM-DD).
    """
    try:
        parsed = datetime.strptime(date_string, format_string)
        return f"Parsed date: {parsed.strftime('%Y-%m-%d')} ({parsed.strftime('%A, %B %d, %Y')})"
    except ValueError as e:
        return f"Failed to parse date: {e}"


@datetime_toolset.tool
def calculate_date_difference(
    date1: str,
    date2: str,
) -> str:
    """Calculate the difference between two dates.

    Args:
        date1: First date (YYYY-MM-DD format).
        date2: Second date (YYYY-MM-DD format).
    """
    try:
        d1 = datetime.strptime(date1, "%Y-%m-%d")
        d2 = datetime.strptime(date2, "%Y-%m-%d")
        diff = abs(d2 - d1)

        return f"""Date difference:
- Days: {diff.days}
- Weeks: {diff.days // 7} weeks and {diff.days % 7} days
- Months (approx): {diff.days // 30}"""
    except ValueError as e:
        return f"Failed to calculate difference: {e}"


@datetime_toolset.tool
def add_time_to_date(
    date_string: str,
    days: int = 0,
    weeks: int = 0,
    months: int = 0,
) -> str:
    """Add time to a date.

    Args:
        date_string: Starting date (YYYY-MM-DD format).
        days: Number of days to add.
        weeks: Number of weeks to add.
        months: Number of months to add (approximate, 30 days).
    """
    try:
        date = datetime.strptime(date_string, "%Y-%m-%d")
        total_days = days + (weeks * 7) + (months * 30)
        new_date = date + timedelta(days=total_days)

        return f"Result: {new_date.strftime('%Y-%m-%d')} ({new_date.strftime('%A, %B %d, %Y')})"
    except ValueError as e:
        return f"Failed to calculate: {e}"


@datetime_toolset.tool
def format_date(
    date_string: str,
    output_format: str = "long",
) -> str:
    """Format a date in various styles.

    Args:
        date_string: Date in YYYY-MM-DD format.
        output_format: Style - 'long', 'short', 'iso', 'relative'.
    """
    try:
        date = datetime.strptime(date_string, "%Y-%m-%d")
        now = datetime.utcnow()

        formats = {
            "long": date.strftime("%A, %B %d, %Y"),
            "short": date.strftime("%m/%d/%Y"),
            "iso": date.strftime("%Y-%m-%dT00:00:00Z"),
            "relative": _get_relative_date(date, now),
        }

        if output_format not in formats:
            return f"Unknown format. Available: {list(formats.keys())}"

        return formats[output_format]
    except ValueError as e:
        return f"Failed to format date: {e}"


def _get_relative_date(date: datetime, now: datetime) -> str:
    """Get a relative date description."""
    diff = (now - date).days

    if diff == 0:
        return "Today"
    elif diff == 1:
        return "Yesterday"
    elif diff == -1:
        return "Tomorrow"
    elif diff > 0:
        if diff < 7:
            return f"{diff} days ago"
        elif diff < 30:
            return f"{diff // 7} weeks ago"
        elif diff < 365:
            return f"{diff // 30} months ago"
        else:
            return f"{diff // 365} years ago"
    else:
        diff = abs(diff)
        if diff < 7:
            return f"In {diff} days"
        elif diff < 30:
            return f"In {diff // 7} weeks"
        elif diff < 365:
            return f"In {diff // 30} months"
        else:
            return f"In {diff // 365} years"
