"""Brand matrix test — every slide type with every brand preset must render cleanly."""

from __future__ import annotations

from pathlib import Path

import pytest
from pptx import Presentation

from pptx_mcp.brand.defaults import PRESETS
from pptx_mcp.engine.generator import DeckGenerator
from pptx_mcp.models.diagrams import (
    CycleStep,
    GanttTask,
    MatrixData,
    MatrixQuadrant,
    OrgNode,
    PyramidLayer,
    SpokeItem,
    VennCircle,
    VennData,
    WaterfallBar,
)
from pptx_mcp.models.slides import (
    AgendaItem,
    CardDefinition,
    ColumnContent,
    ChartData,
    ChartDataSeries,
    ChartElement,
    ChartType,
    FunnelStage,
    IconItem,
    KpiCard,
    PresentationDefinition,
    PresentationMetadata,
    ProcessStep,
    SlideDefinition,
    SlideType,
    SwotData,
    TableCell,
    TableElement,
    TeamMember,
)


def _minimal_slide(slide_type: SlideType) -> SlideDefinition:
    """Create a minimal valid SlideDefinition for the given type."""
    base = {"slide_type": slide_type, "title": f"Test {slide_type.value}"}

    if slide_type == SlideType.TWO_COLUMN:
        base["columns"] = [
            ColumnContent(title="A", bullets=["1"]),
            ColumnContent(title="B", bullets=["2"]),
        ]
    elif slide_type == SlideType.PROS_CONS:
        base["pros"] = ["Pro 1"]
        base["cons"] = ["Con 1"]
    elif slide_type == SlideType.CHART:
        base["elements"] = [
            ChartElement(
                chart_type=ChartType.BAR,
                data=ChartData(
                    categories=["A", "B"],
                    series=[ChartDataSeries(name="S1", values=[1.0, 2.0])],
                ),
            ),
        ]
    elif slide_type == SlideType.COMPARISON:
        base["columns"] = [
            ColumnContent(title="X", bullets=["1"]),
            ColumnContent(title="Y", bullets=["2"]),
        ]
    elif slide_type == SlideType.TABLE:
        base["elements"] = [
            TableElement(rows=[
                [TableCell(text="H1"), TableCell(text="H2")],
                [TableCell(text="V1"), TableCell(text="V2")],
            ]),
        ]
    elif slide_type == SlideType.QUOTE:
        base["body"] = "Test quote."
        base["quote_attribution"] = "Author"
    elif slide_type == SlideType.BIG_NUMBER:
        base["body"] = "99%"
    elif slide_type in (SlideType.PROCESS, SlideType.TIMELINE, SlideType.STEP_CARDS):
        base["steps"] = [
            ProcessStep(title="S1", description="D1"),
            ProcessStep(title="S2", description="D2"),
        ]
    elif slide_type == SlideType.DASHBOARD:
        base["kpis"] = [
            KpiCard(value="100", label="L1"),
            KpiCard(value="200", label="L2"),
        ]
    elif slide_type == SlideType.ICON_GRID:
        base["icons"] = [
            IconItem(icon="★", title="I1"),
            IconItem(icon="★", title="I2"),
        ]
    elif slide_type == SlideType.CARD_GRID:
        base["cards"] = [
            CardDefinition(title="Card A", body="Description A", bullets=["Bullet 1"]),
            CardDefinition(title="Card B", body="Description B", bullets=["Bullet 2"]),
        ]
    elif slide_type == SlideType.IMAGE_TEXT:
        base["body"] = "Description"
        base["bullets"] = ["Point 1"]
    elif slide_type == SlideType.TEAM:
        base["team_members"] = [
            TeamMember(name="Jane Doe", role="CEO"),
            TeamMember(name="John Smith", role="CTO"),
        ]
    elif slide_type == SlideType.CLOSING:
        base["subtitle"] = "Thanks"
        base["cta_text"] = "Contact Us"
    elif slide_type == SlideType.SWOT:
        base["swot"] = SwotData(
            strengths=["S1"], weaknesses=["W1"],
            opportunities=["O1"], threats=["T1"],
        )
    elif slide_type == SlideType.FUNNEL:
        base["funnel_stages"] = [
            FunnelStage(label="Top", value="100"),
            FunnelStage(label="Mid", value="50"),
            FunnelStage(label="Bot", value="10"),
        ]
    elif slide_type == SlideType.AGENDA:
        base["agenda_items"] = [
            AgendaItem(title="Item 1"),
            AgendaItem(title="Item 2"),
        ]
    elif slide_type == SlideType.CONTENT:
        base["bullets"] = ["Point 1", "Point 2"]
    # Diagram types (v0.6.0)
    elif slide_type == SlideType.ORG_CHART:
        base["org_chart"] = OrgNode(
            id="root", name="CEO", role="Chief Executive",
            children=[OrgNode(id="c1", name="VP", role="Vice President")],
        )
    elif slide_type == SlideType.MATRIX:
        base["matrix"] = MatrixData(
            top_left=MatrixQuadrant(label="TL", items=["a"]),
            top_right=MatrixQuadrant(label="TR"),
            bottom_left=MatrixQuadrant(label="BL"),
            bottom_right=MatrixQuadrant(label="BR"),
        )
    elif slide_type == SlideType.PYRAMID:
        base["pyramid_layers"] = [
            PyramidLayer(label="Top"),
            PyramidLayer(label="Mid"),
            PyramidLayer(label="Base"),
        ]
    elif slide_type == SlideType.VENN:
        base["venn"] = VennData(
            circles=[VennCircle(label="A"), VennCircle(label="B")],
            intersection_label="A+B",
        )
    elif slide_type == SlideType.WATERFALL:
        base["waterfall_bars"] = [
            WaterfallBar(label="Start", value=100, bar_type="total"),
            WaterfallBar(label="Add", value=20, bar_type="increase"),
            WaterfallBar(label="End", value=120, bar_type="total"),
        ]
    elif slide_type == SlideType.HUB_SPOKE:
        base["hub_spoke_center"] = "Core"
        base["spokes"] = [SpokeItem(label="S1"), SpokeItem(label="S2")]
    elif slide_type == SlideType.CYCLE:
        base["cycle_steps"] = [CycleStep(label="A"), CycleStep(label="B"), CycleStep(label="C")]
    elif slide_type == SlideType.GANTT:
        base["gantt_tasks"] = [
            GanttTask(label="T1", start=0.0, duration=0.3),
            GanttTask(label="T2", start=0.2, duration=0.4),
        ]
        base["gantt_phases"] = ["P1", "P2"]
    # TITLE, SECTION, DIAGRAM, BLANK just need title (already set)

    return SlideDefinition(**base)


# All 32 slide types
ALL_TYPES = list(SlideType)
# All brand presets
ALL_PRESETS = list(PRESETS.keys())


@pytest.mark.parametrize("slide_type", ALL_TYPES, ids=[t.value for t in ALL_TYPES])
@pytest.mark.parametrize("preset_name", ALL_PRESETS)
def test_brand_matrix(slide_type: SlideType, preset_name: str, tmp_path: Path) -> None:
    """Every slide type must render cleanly with every brand preset."""
    brand = PRESETS[preset_name].model_copy(deep=True)
    generator = DeckGenerator(brand=brand)
    slide_def = _minimal_slide(slide_type)
    definition = PresentationDefinition(
        metadata=PresentationMetadata(title="Matrix Test"),
        slides=[slide_def],
    )
    out = tmp_path / f"{preset_name}_{slide_type.value}.pptx"
    path = generator.generate(definition, out)
    assert path.exists()
    prs = Presentation(str(path))
    assert len(prs.slides) == 1
