"""Pydantic models for element-level slide editing."""

from __future__ import annotations

from enum import Enum
from typing import Optional

from pydantic import BaseModel, Field, model_validator


class ElementLocator(BaseModel):
    """Identifies a shape on a slide by index, name, or text content.

    Resolution priority: index → name (exact) → text_match (substring).
    At least one field must be provided.
    """

    index: Optional[int] = Field(default=None, ge=0, description="0-based shape index from list_slide_elements")
    name: Optional[str] = Field(default=None, description="Exact match on shape.name")
    text_match: Optional[str] = Field(default=None, description="Substring match on shape text content")

    @model_validator(mode="after")
    def at_least_one_field(self) -> ElementLocator:
        if self.index is None and self.name is None and self.text_match is None:
            raise ValueError("ElementLocator requires at least one of: index, name, text_match")
        return self


class ElementModification(BaseModel):
    """Flat modification model — only non-None fields are applied to the target shape."""

    # Position / size (inches)
    left: Optional[float] = Field(default=None, ge=-2.0, le=50.0, description="Left edge in inches")
    top: Optional[float] = Field(default=None, ge=-2.0, le=50.0, description="Top edge in inches")
    width: Optional[float] = Field(default=None, ge=0.01, le=50.0, description="Width in inches")
    height: Optional[float] = Field(default=None, ge=0.01, le=50.0, description="Height in inches")
    rotation: Optional[float] = Field(default=None, ge=0.0, le=360.0, description="Rotation in degrees")

    # Text
    text: Optional[str] = Field(default=None, description="Replace all text in shape")

    # Font
    font_name: Optional[str] = None
    font_size: Optional[float] = Field(default=None, gt=0, le=500, description="Font size in points")
    font_bold: Optional[bool] = None
    font_italic: Optional[bool] = None
    font_color: Optional[str] = Field(default=None, description="Hex color, e.g. '#1A2B3C'")

    # Paragraph
    text_alignment: Optional[str] = Field(
        default=None, description="Text alignment: left, center, right, justify"
    )

    # Shape styling
    fill_color: Optional[str] = Field(
        default=None, description="Hex fill color or 'none' for transparent"
    )
    border_color: Optional[str] = Field(
        default=None, description="Hex border color or 'none' for no border"
    )
    border_width: Optional[float] = Field(default=None, gt=0, le=50, description="Border width in points")

    # Metadata
    name: Optional[str] = Field(default=None, description="Rename the shape")


class ElementInfo(BaseModel):
    """Shape information returned by list/modify operations."""

    index: int
    shape_id: int
    name: str
    shape_type: str
    left: float = Field(description="Left edge in inches")
    top: float = Field(description="Top edge in inches")
    width: float = Field(description="Width in inches")
    height: float = Field(description="Height in inches")
    rotation: float = 0.0
    text_preview: Optional[str] = Field(default=None, description="First 100 chars of text")
    has_text: bool = False
    font_name: Optional[str] = None
    font_size: Optional[float] = None
    fill_color: Optional[str] = None
    border_color: Optional[str] = None
    child_count: Optional[int] = Field(default=None, description="Number of children (groups only)")


class BatchModification(BaseModel):
    """A locator + modification pair for batch editing."""

    locator: ElementLocator
    modification: ElementModification


class FindReplaceResult(BaseModel):
    """Result of a find-and-replace operation on a single shape."""

    slide_index: int
    shape_name: str
    old_text: str
    new_text: str
    replacements: int


class AlignmentType(str, Enum):
    LEFT = "left"
    CENTER = "center"
    RIGHT = "right"
    TOP = "top"
    MIDDLE = "middle"
    BOTTOM = "bottom"
    DISTRIBUTE_H = "distribute_h"
    DISTRIBUTE_V = "distribute_v"
