"""Integration tests for visual quality fixes — font scaling, contrast, card colors."""

from __future__ import annotations

from pathlib import Path

import pytest
from pptx import Presentation

from pptx_mcp.brand.defaults import PRESETS, get_preset
from pptx_mcp.engine.generator import DeckGenerator
from pptx_mcp.models.slides import (
    IconItem,
    KpiCard,
    PresentationDefinition,
    PresentationMetadata,
    ProcessStep,
    SlideDefinition,
    SlideType,
)


def _make_definition(slides: list[SlideDefinition]) -> PresentationDefinition:
    return PresentationDefinition(
        metadata=PresentationMetadata(title="Visual QA", author="Test"),
        slides=slides,
    )


@pytest.fixture
def output_dir(tmp_path: Path) -> Path:
    return tmp_path


class TestFontScaling:
    def test_dashboard_scales_with_count(self, output_dir: Path) -> None:
        """Dashboard with 4 and 10 KPIs should both generate without error."""
        brand = get_preset("executive")
        gen = DeckGenerator(brand=brand)
        for count in (4, 10):
            kpis = [
                KpiCard(label=f"KPI {i + 1}", value=f"${i * 100}")
                for i in range(count)
            ]
            defn = _make_definition([
                SlideDefinition(
                    slide_type=SlideType.DASHBOARD,
                    title="Metrics",
                    kpis=kpis,
                ),
            ])
            path = output_dir / f"dashboard_{count}.pptx"
            gen.generate(defn, path)
            assert path.exists()
            prs = Presentation(str(path))
            assert len(prs.slides) == 1

    def test_icon_grid_scales(self, output_dir: Path) -> None:
        """Icon grid with 6 and 12 icons should both generate."""
        brand = get_preset("minimal")
        gen = DeckGenerator(brand=brand)
        for count in (6, 12):
            icons = [
                IconItem(icon="🔵", title=f"Item {i + 1}", description="Desc")
                for i in range(count)
            ]
            defn = _make_definition([
                SlideDefinition(
                    slide_type=SlideType.ICON_GRID,
                    title="Features",
                    icons=icons,
                ),
            ])
            path = output_dir / f"icons_{count}.pptx"
            gen.generate(defn, path)
            assert path.exists()

    def test_step_cards_scales(self, output_dir: Path) -> None:
        """Step cards with 3 and 5 steps should both generate."""
        brand = get_preset("corporate")
        gen = DeckGenerator(brand=brand)
        for count in (3, 5):
            steps = [
                ProcessStep(title=f"Step {i + 1}", description="Details here")
                for i in range(count)
            ]
            defn = _make_definition([
                SlideDefinition(
                    slide_type=SlideType.STEP_CARDS,
                    title="Process",
                    steps=steps,
                ),
            ])
            path = output_dir / f"steps_{count}.pptx"
            gen.generate(defn, path)
            assert path.exists()


class TestContrast:
    def test_light_accent_contrast(self, output_dir: Path) -> None:
        """Creative preset (light accent) step cards should render without error."""
        brand = get_preset("creative")
        gen = DeckGenerator(brand=brand)
        steps = [
            ProcessStep(title=f"Step {i + 1}", description="Details")
            for i in range(3)
        ]
        defn = _make_definition([
            SlideDefinition(
                slide_type=SlideType.STEP_CARDS,
                title="Creative Steps",
                steps=steps,
            ),
        ])
        path = output_dir / "creative_steps.pptx"
        gen.generate(defn, path)
        assert path.exists()


class TestBulletOverflow:
    def test_many_bullets(self, output_dir: Path) -> None:
        """12 bullets should render without error (dynamic height)."""
        brand = get_preset("executive")
        gen = DeckGenerator(brand=brand)
        bullets = [f"Point number {i + 1} with some detail" for i in range(12)]
        defn = _make_definition([
            SlideDefinition(
                slide_type=SlideType.CONTENT,
                title="Many Points",
                bullets=bullets,
            ),
        ])
        path = output_dir / "many_bullets.pptx"
        gen.generate(defn, path)
        assert path.exists()


class TestCardBrandColors:
    def test_cards_use_brand_surface(self, output_dir: Path) -> None:
        """Parse a generated PPTX and verify card fill matches brand surface color."""
        brand = get_preset("consulting")
        gen = DeckGenerator(brand=brand)
        steps = [
            ProcessStep(title="Assess", description="Evaluate current state"),
            ProcessStep(title="Design", description="Plan the solution"),
            ProcessStep(title="Implement", description="Execute the plan"),
        ]
        defn = _make_definition([
            SlideDefinition(
                slide_type=SlideType.STEP_CARDS,
                title="Approach",
                steps=steps,
            ),
        ])
        path = output_dir / "brand_cards.pptx"
        gen.generate(defn, path)

        prs = Presentation(str(path))
        slide = prs.slides[0]

        # Find rounded rectangle shapes (the card backgrounds)
        from pptx.enum.shapes import MSO_SHAPE_TYPE
        surface_hex = brand.colors.surface.lstrip("#").upper()

        found_surface = False
        for shape in slide.shapes:
            if shape.shape_type == MSO_SHAPE_TYPE.AUTO_SHAPE:
                try:
                    fill_rgb = shape.fill.fore_color.rgb
                    shape_hex = f"{fill_rgb}".upper()
                    if shape_hex == surface_hex:
                        found_surface = True
                        break
                except Exception:
                    continue

        assert found_surface, f"No shape found with brand surface color {surface_hex}"
