"""Schemas — Resume / JD / document parsing."""

from enum import Enum
from typing import Any
from uuid import UUID

from pydantic import BaseModel, Field, model_validator

from app.schemas.common import StubMeta


class DocumentType(str, Enum):
    PDF = "pdf"
    DOCX = "docx"
    TXT = "txt"
    HTML = "html"
    IMAGE = "image"
    MARKDOWN = "markdown"


class ParseTarget(str, Enum):
    RAW_TEXT = "raw_text"
    STRUCTURED_QA = "structured_qa"
    RUBRIC = "rubric"
    SYLLABUS = "syllabus"
    RESUME = "resume"
    JOB_DESCRIPTION = "job_description"


class DocumentParseRequest(BaseModel):
    """POST /api/v1/documents/parse

    Provide either `content_base64` or `source_url` (exactly one).
    """

    correlation_id: UUID | None = None
    document_type: DocumentType
    parse_target: ParseTarget = ParseTarget.RAW_TEXT
    content_base64: str | None = Field(
        default=None,
        description="Base64-encoded document bytes",
    )
    source_url: str | None = Field(
        default=None,
        description="Internal/presigned URL the Gateway may fetch",
    )
    filename: str | None = None
    language: str = Field(default="en", min_length=2, max_length=10)
    options: dict[str, Any] = Field(
        default_factory=dict,
        description="OCR, page range, extract_tables, etc.",
    )

    @model_validator(mode="after")
    def require_one_source(self) -> "DocumentParseRequest":
        has_content = bool(self.content_base64)
        has_url = bool(self.source_url)
        if has_content == has_url:
            raise ValueError("Provide exactly one of content_base64 or source_url")
        return self


class ParsedBlock(BaseModel):
    block_id: str
    block_type: str = "paragraph"
    text: str
    page: int | None = None
    metadata: dict[str, Any] = Field(default_factory=dict)


class DocumentParseResponse(StubMeta):
    correlation_id: UUID | None = None
    document_type: DocumentType
    parse_target: ParseTarget
    raw_text: str | None = None
    blocks: list[ParsedBlock] = Field(default_factory=list)
    structured: dict[str, Any] = Field(default_factory=dict)
