from dataclasses import replace
from datetime import date, timedelta

import pytest

from adventurestay_utils import (
    AdventurePackage,
    PackageBookingValidator,
    InvalidDateRangeError,
    InvalidGuestCountError,
)


def sample_package(**overrides):
    base = AdventurePackage(
        package_id="PKG1",
        category="HILLS_STAYCATION",
        name="Hills Weekend Escape",
        location="Shillong",
        base_price_per_night=120.0,
        max_guests=4,
        min_nights=2,
        max_nights=5,
        includes_meals=True,
        includes_guide=False,
    )
    return replace(base, **overrides)


def test_validate_dates_success():
    package = sample_package()
    nights = PackageBookingValidator.validate_dates(
        date(2025, 1, 10), date(2025, 1, 12), package
    )
    assert nights == 2


def test_validate_dates_invalid_range():
    package = sample_package()
    with pytest.raises(InvalidDateRangeError):
        PackageBookingValidator.validate_dates(
            date(2025, 1, 10), date(2025, 1, 10), package
        )


def test_validate_dates_outside_limits():
    package = sample_package()
    with pytest.raises(InvalidDateRangeError):
        PackageBookingValidator.validate_dates(
            date(2025, 1, 10), date(2025, 1, 25), package
        )


def test_validate_guests_success():
    package = sample_package()
    PackageBookingValidator.validate_guests(2, package)


@pytest.mark.parametrize("guest_count", [0, -1, 5])
def test_validate_guests_invalid_counts(guest_count):
    package = sample_package()
    with pytest.raises(InvalidGuestCountError):
        PackageBookingValidator.validate_guests(guest_count, package)


def test_create_booking_request():
    package = sample_package()
    start = date(2025, 2, 1)
    end = start + timedelta(days=2)
    booking_request = PackageBookingValidator.create_booking_request(
        package, start, end, 2
    )
    assert booking_request.package_id == package.package_id
    assert booking_request.num_guests == 2
