"""Calendar calculations and date utilities.

This module provides calendar-related operations and utilities.
"""

from datetime import date, datetime
from typing import Any, Dict

from .temporal import Day, Hour, Month, Week, Year


class Calendar:
    """Calendar utilities for temporal calculations."""

    @staticmethod
    def now() -> Dict[str, Any]:
        """Get current date and time components.

        Returns:
            Dictionary with year, month, day, hour, minute, second
        """
        now = datetime.now()
        return {
            "year": Year(now.year),
            "month": Month(now.month),
            "day": Day(now.day),
            "hour": Hour(now.hour, now.minute, now.second),
            "week": Calendar.get_week(now.year, now.month, now.day),
            "datetime": now,
        }

    @staticmethod
    def get_week(year: int, month: int, day: int) -> Week:
        """Get the week number for a given date.

        Args:
            year: The year
            month: The month (1-12)
            day: The day of month (1-31)

        Returns:
            Week object containing week number and year
        """
        d = date(year, month, day)
        week_num = d.isocalendar()[1]
        return Week(week_num, year)

    @staticmethod
    def days_in_month(year: int, month: int) -> int:
        """Get the number of days in a month.

        Args:
            year: The year
            month: The month (1-12)

        Returns:
            Number of days in that month
        """
        if month == 2:
            # February - check for leap year
            return 29 if (year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)) else 28
        return [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1]

    @staticmethod
    def is_leap_year(year: int) -> bool:
        """Check if a year is a leap year.

        Args:
            year: The year to check

        Returns:
            True if leap year, False otherwise
        """
        return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
