from datetime import date, datetime

from pydantic import BaseModel, Field, ValidationInfo, field_validator


class CertificateCreate(BaseModel):
    learner_name: str = Field(min_length=1, max_length=64)
    learner_phone: str = Field(min_length=6, max_length=32)
    project_code: str = Field(min_length=2, max_length=16)
    certificate_name: str | None = Field(default=None, max_length=128)
    class_name: str | None = Field(default=None, max_length=128)
    course_name: str | None = Field(default=None, max_length=128)
    stage_name: str | None = Field(default=None, max_length=128)
    course_start_date: date
    course_end_date: date
    issue_date: date
    template_code: str | None = Field(default=None, min_length=1, max_length=32)
    remark: str | None = None

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

    @field_validator("learner_name", "learner_phone")
    @classmethod
    def strip_identity(cls, value: str) -> str:
        return value.strip()

    @field_validator("course_end_date")
    @classmethod
    def validate_course_period(cls, value: date, info: ValidationInfo) -> date:
        start_date = info.data.get("course_start_date")
        if start_date and value < start_date:
            raise ValueError("课程结束日期不能早于课程开始日期")
        return value


class CertificateOut(BaseModel):
    id: int
    learner_id: int
    learner_name: str | None = None
    learner_phone: str | None = None
    import_batch_id: int | None = None
    project_code: str
    certificate_no: str
    certificate_name: str
    class_name: str | None
    course_name: str | None
    stage_name: str | None
    course_start_date: date | None
    course_end_date: date | None
    issue_date: date
    template_code: str
    status: str
    pdf_status: str
    created_at: datetime
    updated_at: datetime

    model_config = {"from_attributes": True}


class PdfPregenerationJobCreate(BaseModel):
    certificate_ids: list[int] = Field(default_factory=list, max_length=5000)
    import_batch_id: int | None = None


class PdfPregenerationJobOut(BaseModel):
    id: str
    status: str
    total: int
    completed: int
    generated: int
    cached: int
    skipped: int
    failed: int
    percent: int
    concurrency_limit: int
    errors: list[str]
    created_at: datetime
    finished_at: datetime | None = None
