"""Pydantic models for brand configuration and style guidelines."""

from __future__ import annotations

from enum import Enum
from typing import Literal, Optional

from pydantic import BaseModel, Field


class ToneStyle(str, Enum):
    EXECUTIVE = "executive"
    TECHNICAL = "technical"
    CREATIVE = "creative"
    MINIMAL = "minimal"
    CORPORATE = "corporate"
    HEALTHCARE = "healthcare"
    STARTUP = "startup"
    ACADEMIC = "academic"
    GOVERNMENT = "government"
    FINANCE = "finance"
    NONPROFIT = "nonprofit"


class ColorPalette(BaseModel):
    """Brand color definitions."""

    primary: str = Field(description="Primary brand color (hex)")
    secondary: str = Field(description="Secondary brand color (hex)")
    accent: str = Field(description="Accent/highlight color (hex)")
    background: str = Field(default="#FFFFFF", description="Slide background color (hex)")
    text_primary: str = Field(default="#1A1A2E", description="Primary text color (hex)")
    text_secondary: str = Field(default="#4A4A5A", description="Secondary/muted text color (hex)")
    success: str = Field(default="#28A745", description="Positive/success color (hex)")
    danger: str = Field(default="#DC3545", description="Negative/danger color (hex)")
    surface: str = Field(default="#F8F9FA", description="Card/content area background (hex)")
    border: str = Field(default="#E0E0E0", description="Divider and card border color (hex)")
    chart_colors: list[str] = Field(
        default_factory=list,
        description="Ordered list of colors for chart data series",
    )
    custom_tokens: dict[str, str] = Field(
        default_factory=dict,
        description="Arbitrary named color tokens, e.g. {'surface': '#F5F5F5', 'border': '#E0E0E0'}",
    )


class FontConfig(BaseModel):
    """Typography hierarchy configuration."""

    heading_font: str = Field(default="Calibri", description="Font family for headings")
    body_font: str = Field(default="Calibri", description="Font family for body text")
    mono_font: str = Field(default="Consolas", description="Font family for monospace/code")
    title_size: int = Field(default=36, description="Title text size in points")
    heading_size: int = Field(default=28, description="Heading text size in points")
    subheading_size: int = Field(default=20, description="Subheading text size in points")
    body_size: int = Field(default=16, description="Body text size in points")
    caption_size: int = Field(default=12, description="Caption/small text size in points")
    line_spacing: float = Field(default=1.2, description="Default line spacing multiplier")
    display_font: Optional[str] = Field(default=None, description="Display/hero font (defaults to heading_font)")
    display_size: int = Field(default=44, description="Display text size in points")
    font_weight_heading: str = Field(default="Bold", description="Font weight for headings")
    font_weight_body: str = Field(default="Regular", description="Font weight for body text")
    paragraph_spacing: float = Field(default=6.0, description="Space after paragraphs in points")


class SpacingConfig(BaseModel):
    """Layout spacing and grid rules."""

    margin_left: float = Field(default=0.7, description="Left margin in inches")
    margin_right: float = Field(default=0.7, description="Right margin in inches")
    margin_top: float = Field(default=0.8, description="Top margin in inches")
    margin_bottom: float = Field(default=0.5, description="Bottom margin in inches")
    title_top: float = Field(default=0.4, description="Title top position in inches")
    content_top: float = Field(default=1.6, description="Content area top position in inches")
    element_gap: float = Field(default=0.3, description="Gap between elements in inches")
    column_gap: float = Field(default=0.4, description="Gap between columns in inches")
    padding: float = Field(default=0.2, description="Internal padding for boxes in inches")
    base_unit_pt: int = Field(default=8, description="Base spacing grid unit in points")


class LayoutRules(BaseModel):
    """Composition and layout rules."""

    max_bullets_per_slide: int = Field(default=6, description="Maximum bullet points per slide")
    max_words_per_bullet: int = Field(default=15, description="Maximum words per bullet point")
    max_words_per_slide: int = Field(default=75, description="Maximum total words per slide")
    min_font_size: int = Field(default=12, description="Minimum font size in points")
    prefer_visual_balance: bool = Field(
        default=True, description="Prefer balanced left-right composition"
    )
    use_accent_sparingly: bool = Field(
        default=True, description="Limit accent color to key elements"
    )
    title_every_slide: bool = Field(default=True, description="Require titles on every slide")


class HeaderFooterConfig(BaseModel):
    """Header, footer, and slide numbering configuration."""

    show_slide_numbers: bool = Field(default=False, description="Show slide numbers")
    show_date: bool = Field(default=False, description="Show date in footer")
    date_text: Optional[str] = Field(default=None, description="Custom date text (auto if None)")
    show_company_name: bool = Field(default=False, description="Show company name in footer")
    confidential_marking: Optional[str] = Field(
        default=None, description="Confidential/draft marking text"
    )
    skip_title_slide: bool = Field(
        default=True, description="Skip footer on title and closing slides"
    )


class LogoConfig(BaseModel):
    """Logo placement configuration."""

    path: Optional[str] = Field(default=None, description="Path to logo image")
    placement: Literal["top_left", "top_right", "bottom_left", "bottom_right"] = Field(
        default="top_left", description="Logo position on slide"
    )
    max_height: float = Field(default=0.5, ge=0.1, le=2.0, description="Max logo height in inches")
    skip_on: list[str] = Field(
        default_factory=lambda: ["title", "closing"],
        description="Slide types to skip logo on",
    )


class ShapeStyleConfig(BaseModel):
    """Global shape appearance controls."""

    card_corner_radius: float = Field(
        default=0.08, ge=0.0, le=0.5,
        description="Corner radius for rounded rectangles (0.0=sharp, 0.5=pill)"
    )
    card_shadow: bool = Field(default=False, description="Apply drop shadow to card shapes")
    shadow_blur_pt: float = Field(default=4.0, description="Shadow blur radius in points")
    shadow_offset_pt: float = Field(default=3.0, description="Shadow offset distance in points")
    shadow_opacity_pct: int = Field(default=25, ge=0, le=100, description="Shadow opacity percentage")
    card_border_width_pt: float = Field(
        default=0.75, description="Card border width in points (0=no border)"
    )
    show_accent_bar: bool = Field(
        default=True, description="Show accent underline below slide titles"
    )
    shadow_preset: Literal["none", "subtle", "medium", "elevated"] = Field(
        default="none", description="Named shadow preset (overrides card_shadow fields when != 'none')"
    )
    edge_bar: Literal["none", "left", "top"] = Field(
        default="none", description="Edge accent bar placement"
    )
    edge_bar_width: float = Field(default=0.15, description="Edge bar width in inches")
    divider_style: Literal["none", "thin_line", "dotted"] = Field(
        default="none", description="Divider line style"
    )
    line_dash_style: Literal["solid", "dash", "dot", "dash_dot", "long_dash"] = Field(
        default="solid", description="Default line dash pattern"
    )
    text_auto_fit: bool = Field(
        default=False, description="Shrink text to fit shape when True"
    )


class BrandConfig(BaseModel):
    """Complete brand configuration for presentation generation."""

    name: str = Field(description="Brand/company name")
    colors: ColorPalette
    fonts: FontConfig = Field(default_factory=FontConfig)
    spacing: SpacingConfig = Field(default_factory=SpacingConfig)
    layout_rules: LayoutRules = Field(default_factory=LayoutRules)
    header_footer: HeaderFooterConfig = Field(default_factory=HeaderFooterConfig)
    shape_style: ShapeStyleConfig = Field(default_factory=ShapeStyleConfig)
    tone: ToneStyle = Field(default=ToneStyle.EXECUTIVE)
    logo_path: Optional[str] = Field(default=None, description="Path to brand logo image")
    logo: LogoConfig = Field(default_factory=LogoConfig)
    footer_text: Optional[str] = Field(default=None, description="Default footer/confidential text")
    template_path: Optional[str] = Field(
        default=None, description="Path to a base PPTX template file"
    )
