from typing import Any

from pydantic import BaseModel, ConfigDict, EmailStr, model_validator


class UserSpbuAssignmentCreate(BaseModel):
    spbu_id: int
    role_id: int


class UserSpbuAssignmentResponse(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: int
    user_id: int
    spbu_id: int
    role_id: int
    spbu_name: str | None = None
    role_name: str | None = None
    role_can_be_scheduled: bool = False

    @model_validator(mode="before")
    @classmethod
    def _extract_from_orm(cls, data: Any) -> Any:
        if isinstance(data, dict):
            return data
        # Only access role — it is eagerly loaded via selectinload.
        # Do NOT access .spbu here; it is not eagerly loaded and triggers
        # a lazy load that fails in async SQLAlchemy sessions.
        role = getattr(data, "role", None)
        return {
            "id": data.id,
            "user_id": data.user_id,
            "spbu_id": data.spbu_id,
            "role_id": data.role_id,
            "spbu_name": None,
            "role_name": role.nama if role else None,
            "role_can_be_scheduled": role.can_be_scheduled if role else False,
        }


class UserCreate(BaseModel):
    name: str
    email: EmailStr
    username: str | None = None
    password: str | None = None
    is_superadmin: bool = False


class UserUpdate(BaseModel):
    name: str | None = None
    email: EmailStr | None = None
    username: str | None = None
    password: str | None = None
    is_active: bool | None = None
    is_superadmin: bool | None = None


class UserResponse(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: int
    name: str
    email: str
    username: str | None = None
    is_superadmin: bool
    is_active: bool
    assignments: list[UserSpbuAssignmentResponse] = []
