"""Tests for v0.7.0 BrandConfig model extensions."""

from __future__ import annotations

import pytest

from pptx_mcp.models.brand import (
    BrandConfig,
    ColorPalette,
    FontConfig,
    LogoConfig,
    ShapeStyleConfig,
    SpacingConfig,
)
from pptx_mcp.brand.defaults import get_preset


# ---------------------------------------------------------------------------
# ColorPalette new fields
# ---------------------------------------------------------------------------

def test_color_palette_surface_default():
    cp = ColorPalette(primary="#000", secondary="#111", accent="#222")
    assert cp.surface == "#F8F9FA"


def test_color_palette_border_default():
    cp = ColorPalette(primary="#000", secondary="#111", accent="#222")
    assert cp.border == "#E0E0E0"


def test_color_palette_surface_custom():
    cp = ColorPalette(primary="#000", secondary="#111", accent="#222", surface="#FAFAFA")
    assert cp.surface == "#FAFAFA"


# ---------------------------------------------------------------------------
# FontConfig new fields
# ---------------------------------------------------------------------------

def test_font_config_display_font_default_none():
    fc = FontConfig()
    assert fc.display_font is None


def test_font_config_display_size_default():
    fc = FontConfig()
    assert fc.display_size == 44


def test_font_config_font_weight_defaults():
    fc = FontConfig()
    assert fc.font_weight_heading == "Bold"
    assert fc.font_weight_body == "Regular"


def test_font_config_paragraph_spacing_default():
    fc = FontConfig()
    assert fc.paragraph_spacing == 6.0


def test_font_config_display_font_custom():
    fc = FontConfig(display_font="Impact")
    assert fc.display_font == "Impact"


# ---------------------------------------------------------------------------
# SpacingConfig new fields
# ---------------------------------------------------------------------------

def test_spacing_config_base_unit_default():
    sc = SpacingConfig()
    assert sc.base_unit_pt == 8


def test_spacing_config_base_unit_custom():
    sc = SpacingConfig(base_unit_pt=12)
    assert sc.base_unit_pt == 12


# ---------------------------------------------------------------------------
# ShapeStyleConfig new fields
# ---------------------------------------------------------------------------

def test_shape_style_shadow_preset_default():
    ss = ShapeStyleConfig()
    assert ss.shadow_preset == "none"


def test_shape_style_edge_bar_default():
    ss = ShapeStyleConfig()
    assert ss.edge_bar == "none"


def test_shape_style_edge_bar_width_default():
    ss = ShapeStyleConfig()
    assert ss.edge_bar_width == 0.15


def test_shape_style_divider_style_default():
    ss = ShapeStyleConfig()
    assert ss.divider_style == "none"


def test_shape_style_line_dash_style_default():
    ss = ShapeStyleConfig()
    assert ss.line_dash_style == "solid"


def test_shape_style_text_auto_fit_default():
    ss = ShapeStyleConfig()
    assert ss.text_auto_fit is False


def test_shape_style_shadow_preset_values():
    for val in ("none", "subtle", "medium", "elevated"):
        ss = ShapeStyleConfig(shadow_preset=val)
        assert ss.shadow_preset == val


def test_shape_style_edge_bar_values():
    for val in ("none", "left", "top"):
        ss = ShapeStyleConfig(edge_bar=val)
        assert ss.edge_bar == val


def test_shape_style_divider_style_values():
    for val in ("none", "thin_line", "dotted"):
        ss = ShapeStyleConfig(divider_style=val)
        assert ss.divider_style == val


def test_shape_style_line_dash_values():
    for val in ("solid", "dash", "dot", "dash_dot", "long_dash"):
        ss = ShapeStyleConfig(line_dash_style=val)
        assert ss.line_dash_style == val


# ---------------------------------------------------------------------------
# LogoConfig
# ---------------------------------------------------------------------------

def test_logo_config_defaults():
    lc = LogoConfig()
    assert lc.path is None
    assert lc.placement == "top_left"
    assert lc.max_height == 0.5
    assert lc.skip_on == ["title", "closing"]


def test_logo_config_custom():
    lc = LogoConfig(path="/img/logo.png", placement="bottom_right", max_height=0.8, skip_on=[])
    assert lc.path == "/img/logo.png"
    assert lc.placement == "bottom_right"
    assert lc.max_height == 0.8
    assert lc.skip_on == []


def test_logo_config_max_height_bounds():
    with pytest.raises(Exception):
        LogoConfig(max_height=0.05)  # below ge=0.1
    with pytest.raises(Exception):
        LogoConfig(max_height=2.5)  # above le=2.0


# ---------------------------------------------------------------------------
# BrandConfig integration
# ---------------------------------------------------------------------------

def test_brand_config_has_logo():
    bc = BrandConfig(name="test", colors=ColorPalette(primary="#000", secondary="#111", accent="#222"))
    assert isinstance(bc.logo, LogoConfig)
    assert bc.logo.path is None


def test_brand_config_backward_compat():
    """All new fields have defaults — old-style construction still works."""
    bc = BrandConfig(
        name="test",
        colors=ColorPalette(primary="#000", secondary="#111", accent="#222"),
    )
    assert bc.colors.surface == "#F8F9FA"
    assert bc.fonts.display_font is None
    assert bc.spacing.base_unit_pt == 8
    assert bc.shape_style.shadow_preset == "none"
    assert bc.shape_style.edge_bar == "none"
    assert bc.logo.placement == "top_left"


# ---------------------------------------------------------------------------
# Preset updates
# ---------------------------------------------------------------------------

def test_consulting_preset_shadow_preset():
    bc = get_preset("consulting")
    assert bc.shape_style.shadow_preset == "medium"
    assert bc.shape_style.card_shadow is True


def test_startup_preset_edge_bar():
    bc = get_preset("startup")
    assert bc.shape_style.edge_bar == "left"
    assert bc.shape_style.shadow_preset == "subtle"


def test_minimal_preset_divider_and_autofit():
    bc = get_preset("minimal")
    assert bc.shape_style.divider_style == "thin_line"
    assert bc.shape_style.text_auto_fit is True


def test_all_presets_have_new_fields():
    """Every preset should have the new fields with valid values."""
    for name in ("executive", "technical", "minimal", "creative", "corporate",
                 "consulting", "healthcare", "startup", "academic",
                 "government", "finance", "nonprofit"):
        bc = get_preset(name)
        assert bc.colors.surface is not None
        assert bc.colors.border is not None
        assert bc.fonts.font_weight_heading is not None
        assert bc.spacing.base_unit_pt > 0
        assert bc.shape_style.shadow_preset in ("none", "subtle", "medium", "elevated")
        assert bc.shape_style.edge_bar in ("none", "left", "top")
        assert isinstance(bc.logo, LogoConfig)
