"""Base document model for MongoDB models."""
from datetime import datetime
from typing import Optional

from bson import ObjectId
from pydantic import BaseModel, Field, ConfigDict, field_serializer

from .types import PyObjectId

class BaseDocument(BaseModel):
    """Base class for all MongoDB document models."""
    model_config = ConfigDict(
        arbitrary_types_allowed=True,
        populate_by_name=True,
        json_encoders={ObjectId: str, datetime: lambda d: d.isoformat()},
    )

    id: Optional[PyObjectId] = Field(default=None, alias="_id")
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    @field_serializer("id", when_used="json")
    def _serialize_id(self, v: ObjectId | None):
        """Serialize ObjectId to string for JSON."""
        return str(v) if v is not None else None

    @field_serializer("created_at", "updated_at", when_used="json")
    def _serialize_dt(self, v: datetime | None):
        """Serialize datetime to ISO format string."""
        return v.isoformat() if v else None

    def to_bson(self) -> dict:
        """Produce a dict suitable for PyMongo insert/update."""
        return self.model_dump(by_alias=True, exclude_none=True)

    @classmethod
    def from_bson(cls, doc: dict):
        """Create an instance from a BSON document."""
        return cls.model_validate(doc)
