from __future__ import annotations import uuid from datetime import datetime from typing import Any, List, Optional, Union from pydantic import Field from app.schemas.common import BaseSchema class DocumentCellResponse(BaseSchema): """Document cell in a template.""" id: uuid.UUID format_id: uuid.UUID page_number: int x: float y: float width: float height: float row_no: int column_no: int data_type: str font_family: str | None font_size: float | None font_style: str | None font_color: str | None background_color: str | None border_top: str | None border_right: str | None border_bottom: str | None border_left: str | None padding_top: float padding_right: float padding_bottom: float padding_left: float alignment: str vertical_alignment: str rowspan: int colspan: int static_text: str | None field_name: str | None sequence: int is_dynamic: bool class DocumentCellCreate(BaseSchema): """Create a document cell.""" page_number: int = Field(..., ge=1) x: float y: float width: float = Field(..., gt=0) height: float = Field(..., gt=0) row_no: int = 0 column_no: int = 0 data_type: str = "text" font_family: str | None = None font_size: float | None = None font_style: str | None = None font_color: str | None = None background_color: str | None = None border_top: str | None = None border_right: str | None = None border_bottom: str | None = None border_left: str | None = None padding_top: float = 0.0 padding_right: float = 0.0 padding_bottom: float = 0.0 padding_left: float = 0.0 alignment: str = "left" vertical_alignment: str = "top" rowspan: int = 1 colspan: int = 1 static_text: str | None = None field_name: str | None = None sequence: int = 0 is_dynamic: bool = False class DocumentRegionResponse(BaseSchema): """Region in a template.""" id: uuid.UUID format_id: uuid.UUID page_number: int region_type: str x: float y: float width: float height: float content: dict[str, Any] | None sequence: int class TableColumnResponse(BaseSchema): """Table column definition.""" id: uuid.UUID table_format_id: uuid.UUID column_index: int width: float header_text: str | None data_type: str alignment: str font_family: str | None font_size: float | None class TableRowResponse(BaseSchema): """Table row definition.""" id: uuid.UUID table_format_id: uuid.UUID row_index: int height: float is_header: bool background_color: str | None class TableFormatResponse(BaseSchema): """Table format in a template.""" id: uuid.UUID format_id: uuid.UUID page_number: int x: float y: float width: float height: float rows: int columns: int border_style: str border_width: float border_color: str header_rows: int table_columns: list[TableColumnResponse] = Field(default_factory=list) table_rows: list[TableRowResponse] = Field(default_factory=list) class WatermarkResponse(BaseSchema): """Watermark in a template.""" id: uuid.UUID format_id: uuid.UUID page_number: int | None text: str | None image_path: str | None x: float y: float width: float height: float opacity: float rotation: float font_family: str | None font_size: float | None font_color: str | None class ImageRegionResponse(BaseSchema): """Image region in a template.""" id: uuid.UUID format_id: uuid.UUID page_number: int x: float y: float width: float height: float image_path: str | None image_type: str is_static: bool field_name: str | None class TemplateFingerprintResponse(BaseSchema): """Template fingerprint.""" id: uuid.UUID format_id: uuid.UUID page_dimensions: dict[str, Any] | None logo_coordinates: dict[str, Any] | None header_coordinates: dict[str, Any] | None footer_coordinates: dict[str, Any] | None table_coordinates: dict[str, Any] | None cell_coordinates: dict[str, Any] | None fingerprint_hash: str class TemplateResponse(BaseSchema): """Full template response.""" id: uuid.UUID name: str description: str | None page_width: float page_height: float page_count: int margin_top: float margin_right: float margin_bottom: float margin_left: float fingerprint: dict[str, Any] | None source_document_id: uuid.UUID | None version: int is_active: bool created_by: uuid.UUID | None cells: list[DocumentCellResponse] = Field(default_factory=list) regions: list[DocumentRegionResponse] = Field(default_factory=list) table_formats: list[TableFormatResponse] = Field(default_factory=list) watermarks: list[WatermarkResponse] = Field(default_factory=list) image_regions: list[ImageRegionResponse] = Field(default_factory=list) fingerprint_record: TemplateFingerprintResponse | None = None created_at: datetime updated_at: datetime class TemplateListResponse(BaseSchema): """Minimal template response for lists.""" id: uuid.UUID name: str description: str | None page_width: float page_height: float page_count: int version: int is_active: bool created_at: datetime updated_at: datetime class TemplateRenderRequest(BaseSchema): """Request to render a template to PDF.""" template_id: uuid.UUID data: dict[str, Any] = Field(default_factory=dict, description="Data to populate dynamic fields") output_filename: str | None = Field(None, max_length=255, description="Output filename for generated PDF") images: dict[str, str] | None = Field(None, description="Mapping of field_name to image path for dynamic images") class TemplateRenderResponse(BaseSchema): """Response after rendering a template.""" output_path: str filename: str file_size: int page_count: int rendered_at: datetime class TemplateFieldCreate(BaseSchema): field_label: str field_type: str = "text" display_order: int = 0 required_flag: bool = False class TemplateCreateRequest(BaseSchema): template_name: str source_document_id: Optional[str] = None fields: List[TemplateFieldCreate] = Field(default_factory=list) class MappingNodeRequest(BaseSchema): pk_document_data_id: Union[int, str, None] = None x_coordinate: float y_coordinate: float width: float height: float text_value: Optional[str] = None page_width: Optional[float] = None page_height: Optional[float] = None page_no: Optional[int] = None class TemplateMappingSaveRequest(BaseSchema): field_name: str mapped_nodes: List[MappingNodeRequest] = Field(default_factory=list)