"""Availability and capacity checks for adventure staycation packages."""

from __future__ import annotations

from datetime import date
from typing import Iterable

from .exceptions import PackageNotAvailableError
from .models import AdventureBooking, AdventurePackage, BookingRequest


class PackageAvailabilityChecker:
    """Ensures bookings do not overlap or exceed package capacity."""

    def check_availability(
        self,
        booking_request: BookingRequest,
        package: AdventurePackage,
        existing_bookings: Iterable[AdventureBooking],
    ) -> None:
        if not package.is_active:
            raise PackageNotAvailableError("Package is not currently active.")

        overlapping_guest_count = booking_request.num_guests
        requested_start = booking_request.start_date
        requested_end = booking_request.end_date

        for booking in existing_bookings:
            if booking.package.package_id != package.package_id:
                continue

            if self._dates_overlap(
                requested_start, requested_end, booking.start_date, booking.end_date
            ):
                overlapping_guest_count += booking.num_guests
                if overlapping_guest_count > package.max_guests:
                    raise PackageNotAvailableError(
                        "Requested guests exceed capacity for overlapping bookings."
                    )

        # Capacity is satisfied; if no overlaps existed, we still succeed.

    @staticmethod
    def _dates_overlap(
        start_a: date, end_a: date, start_b: date, end_b: date
    ) -> bool:
        return start_a < end_b and start_b < end_a
