from pydantic import BaseModel
from typing import Optional, TypeVar, Generic, List
from datetime import datetime
from uuid import UUID

T = TypeVar("T")


class BaseResponse(BaseModel):
    """Base response model that all response models inherit from.

    This model provides common fields that are present in all database records,
    including tracking information (created/updated timestamps), user actions
    (created by, updated by, confirmed by), and record status (active, deleted).

    Attributes:
        uu_id (str): Unique identifier for the record, typically a UUID
        created_at (datetime): Timestamp when the record was created
        updated_at (Optional[datetime]): Timestamp when the record was last updated
        created_by (Optional[str]): Username or identifier of the user who created the record
        updated_by (Optional[str]): Username or identifier of the user who last updated the record
        confirmed_by (Optional[str]): Username or identifier of the user who confirmed the record
        is_confirmed (Optional[bool]): Whether the record has been confirmed/approved
        active (Optional[bool]): Whether the record is currently active
        deleted (Optional[bool]): Whether the record has been marked as deleted
        expiry_starts (Optional[datetime]): When the record becomes valid/active
        expiry_ends (Optional[datetime]): When the record expires/becomes inactive
        is_notification_send (Optional[bool]): Whether notifications have been sent for this record
        is_email_send (Optional[bool]): Whether emails have been sent for this record
    """

    uu_id: str
    created_at: datetime
    updated_at: Optional[datetime]
    created_by: Optional[str]
    updated_by: Optional[str]
    confirmed_by: Optional[str]
    is_confirmed: Optional[bool] = None
    active: Optional[bool] = True
    deleted: Optional[bool] = False
    expiry_starts: Optional[datetime]
    expiry_ends: Optional[datetime]
    is_notification_send: Optional[bool] = False
    is_email_send: Optional[bool] = False

    class Config:
        """Pydantic configuration for the base response model.

        Attributes:
            from_attributes (bool): Enables ORM mode for SQLAlchemy integration
        """

        from_attributes = True


class CrudCollection(BaseModel, Generic[T]):
    """Base collection model for paginated responses.

    This model is used to return collections of items with pagination information.
    It is generic over the type of items in the collection, allowing it to be
    used with any response model.

    Type Parameters:
        T: The type of items in the collection

    Attributes:
        page (int): Current page number, 1-based indexing
        size (int): Number of items per page
        total (int): Total number of items across all pages
        order_field (str): Field used for sorting the collection
        order_type (str): Sort direction ('asc' or 'desc')
        items (List[T]): List of items in the current page

    Example:
        ```python
        class UserResponse(BaseResponse):
            name: str
            email: str

        users = CrudCollection[UserResponse](
            page=1,
            size=10,
            total=100,
            order_field="name",
            order_type="asc",
            items=[...]
        )
        ```
    """

    page: int = 1
    size: int = 10
    total: int = 0
    order_field: str = "id"
    order_type: str = "asc"
    items: List[T] = []

    class Config:
        """Pydantic configuration for the collection model.

        Attributes:
            from_attributes (bool): Enables ORM mode for SQLAlchemy integration
        """

        from_attributes = True
