from datetime import datetime

from pydantic import BaseModel, Field, field_validator


class ProjectCourseCreate(BaseModel):
    code: str = Field(min_length=2, max_length=16)
    name: str = Field(min_length=1, max_length=128)
    default_certificate_name: str | None = Field(default=None, max_length=128)
    default_course_name: str | None = Field(default=None, max_length=128)
    default_stage_name: str | None = Field(default=None, max_length=128)
    default_template_code: str = Field(default="classic", min_length=1, max_length=32)

    @field_validator("code")
    @classmethod
    def normalize_code(cls, value: str) -> str:
        return value.strip().upper()

    @field_validator("default_certificate_name", "default_course_name", "default_stage_name")
    @classmethod
    def empty_to_none(cls, value: str | None) -> str | None:
        if value is None:
            return None
        text = value.strip()
        return text or None


class ProjectCourseUpdate(BaseModel):
    name: str | None = Field(default=None, min_length=1, max_length=128)
    default_certificate_name: str | None = Field(default=None, max_length=128)
    default_course_name: str | None = Field(default=None, max_length=128)
    default_stage_name: str | None = Field(default=None, max_length=128)
    default_template_code: str | None = Field(default=None, min_length=1, max_length=32)
    status: str | None = Field(default=None, pattern="^(active|disabled)$")

    @field_validator("default_certificate_name", "default_course_name", "default_stage_name")
    @classmethod
    def empty_to_none(cls, value: str | None) -> str | None:
        if value is None:
            return None
        text = value.strip()
        return text or None


class ProjectCourseOut(BaseModel):
    id: int
    code: str
    name: str
    default_certificate_name: str
    default_course_name: str | None
    default_stage_name: str | None
    default_template_code: str
    status: str
    created_at: datetime
    updated_at: datetime

    model_config = {"from_attributes": True}
