"""Slot validation utilities."""

from __future__ import annotations

from datetime import datetime

from .exceptions import InvalidSlotRangeError
from .models import SportSlot


class SlotRangeValidator:
    """Validates the requested booking slot boundaries."""

    def __init__(self, min_duration_hours: float = 0.5, max_duration_hours: float = 4.0):
        self.min_duration_hours = min_duration_hours
        self.max_duration_hours = max_duration_hours

    def validate(
        self,
        sport_type: str,
        court_id: str,
        start_time: datetime,
        end_time: datetime,
    ) -> SportSlot:
        """Validate slot input and return a SportSlot with computed duration."""
        if not isinstance(start_time, datetime) or not isinstance(end_time, datetime):
            raise InvalidSlotRangeError("start_time and end_time must be datetime objects.")

        normalized_sport = sport_type.upper()
        if normalized_sport not in SportSlot.SUPPORTED_SPORTS:
            raise InvalidSlotRangeError(f"Unsupported sport_type '{sport_type}'.")

        if start_time >= end_time:
            raise InvalidSlotRangeError("start_time must be before end_time.")

        duration_hours = (end_time - start_time).total_seconds() / 3600
        if duration_hours <= 0:
            raise InvalidSlotRangeError("Slot duration must be greater than zero.")

        if duration_hours < self.min_duration_hours:
            raise InvalidSlotRangeError(
                f"Slot duration must be at least {self.min_duration_hours} hour(s)."
            )

        if duration_hours > self.max_duration_hours:
            raise InvalidSlotRangeError(
                f"Slot duration cannot exceed {self.max_duration_hours} hour(s)."
            )

        if not court_id:
            raise InvalidSlotRangeError("court_id is required.")

        return SportSlot(
            sport_type=normalized_sport,
            court_id=court_id,
            start_time=start_time,
            end_time=end_time,
            duration_hours=duration_hours,
        )
