from datetime import datetime
from typing import Optional, Union

from bson import ObjectId
from pydantic import BaseModel, EmailStr, ConfigDict, Field

from app.models.user import User


class UserBase(BaseModel):
    email: EmailStr
    name: str

    model_config = ConfigDict(
        populate_by_name=True,
        arbitrary_types_allowed=True
    )


class UserCreate(UserBase):
    password: str


class UserResponse(UserBase):
    id: str = Field(alias="_id")
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    model_config = ConfigDict(
        populate_by_name=True,
        arbitrary_types_allowed=True,
        json_encoders={ObjectId: str}
    )

    @classmethod
    def from_user_in_db(cls, user_data: Optional[Union[dict, User]]) -> Optional['UserResponse']:
        if not user_data:
            return None

        if isinstance(user_data, dict):
            return cls(
                id=str(user_data["_id"]),
                email=user_data["email"],
                name=user_data["name"],
                created_at=user_data["created_at"],
                updated_at=user_data.get("updated_at")
            )
        else:
            return cls(
                id=user_data.id,
                email=user_data.email,
                name=user_data.name,
                created_at=user_data.created_at,
                updated_at=user_data.updated_at
            )


class Token(BaseModel):
    access_token: str
    token_type: str


class TokenData(BaseModel):
    email: Optional[str] = None
