"""Domain-level exceptions.

These are pure Python exceptions with no Django/DRF dependency. The
interfaces layer is responsible for translating them into HTTP responses.
"""


class DomainError(Exception):
    """Base class for all domain/business-rule violations."""


class AlreadyCheckedOutError(DomainError):
    """Raised when a user tries to check out twice on the same day."""


class NotCheckedInError(DomainError):
    """Raised when a user tries to check out before checking in."""


class AttendanceNotFoundError(DomainError):
    """Raised when today's attendance row does not exist yet."""


class InvalidLeaveRequestError(DomainError):
    """Raised when a leave request fails business validation."""


class LeaveRequestNotPendingError(DomainError):
    """Raised when trying to approve/reject a non-pending leave request."""


class HolidayAlreadyExistsError(DomainError):
    """Raised when creating a holiday for a date that already has one."""


class InvalidAttendanceEditError(DomainError):
    """Raised when an admin manual attendance edit fails validation."""


class UserNotFoundError(DomainError):
    """Raised when a referenced user does not exist."""


class UnknownModuleError(DomainError):
    """Unknown module code."""


class ModuleNotAvailableError(DomainError):
    """The module exists in the registry but cannot be enabled (planned/core/deprecated)."""


class ModuleDependencyError(DomainError):
    """Enabling/disabling would break a module dependency."""

    def __init__(self, message: str, modules: list[str] | None = None):
        super().__init__(message)
        self.modules = modules or []


class PermissionDelegationError(DomainError):
    """A grantor tried to hand out more than they are allowed to delegate."""

    def __init__(self, message: str, permissions: list[str] | None = None):
        super().__init__(message)
        self.permissions = permissions or []


class OrganizationStateError(DomainError):
    """Operation is not valid for the organization's current state."""


class LeaveAlreadyGrantedError(DomainError):
    """Raised when an approved daily leave already exists for that user and date."""
