from typing import Annotated, Any, Literal
from uuid import uuid4

from layercake.extra_types import CnpjStr, CpfStr, NameStr
from pydantic import (
    UUID4,
    BaseModel,
    ConfigDict,
    EmailStr,
    Field,
    StringConstraints,
)


class Org(BaseModel):
    id: UUID4 | str = Field(default_factory=uuid4)
    name: Annotated[str, StringConstraints(strip_whitespace=True)]
    cnpj: CnpjStr | None = None


class User(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True)

    id: UUID4 | str = Field(default_factory=uuid4)
    name: NameStr
    email: EmailStr
    email_verified: bool = False
    cpf: CpfStr | None = None


class Cert(BaseModel):
    exp_interval: int


class Course(BaseModel):
    id: UUID4 = Field(default_factory=uuid4)
    name: str
    cert: Cert | None = None
    access_period: int = 90  # 3 months


class Enrollment(BaseModel):
    id: UUID4 | str = Field(default_factory=uuid4)
    user: User
    course: Course
    progress: int = Field(default=0, ge=0, le=100)
    status: Literal['PENDING'] = 'PENDING'

    def model_dump(
        self,
        exclude=None,
        *args,
        **kwargs,
    ) -> dict[str, Any]:
        return super().model_dump(
            exclude={
                'user': {'email_verified'},
                'course': {'cert', 'access_period'},
            },
            *args,
            **kwargs,
        )
