"""Tests for table enhancements — banding, margins, vertical alignment, table style."""

from __future__ import annotations

import pytest
from pptx import Presentation
from pptx.enum.text import MSO_ANCHOR
from pptx.util import Inches, Pt

from pptx_mcp.engine.generator import DeckGenerator
from pptx_mcp.models.brand import BrandConfig
from pptx_mcp.models.slides import (
    PresentationDefinition,
    PresentationMetadata,
    SlideDefinition,
    SlideType,
    TableCell,
    TableElement,
    TableStyle,
)


def _generate_table_deck(
    table_elem: TableElement,
    brand: BrandConfig | None = None,
    tmp_path_factory=None,
) -> Presentation:
    """Generate a one-slide TABLE deck and return the Presentation object."""
    from pptx_mcp.brand.config import resolve_brand_config

    brand = brand or resolve_brand_config()
    defn = PresentationDefinition(
        metadata=PresentationMetadata(title="Table Test"),
        slides=[
            SlideDefinition(
                slide_type=SlideType.TABLE,
                title="Test Table",
                elements=[table_elem],
            ),
        ],
    )
    gen = DeckGenerator(brand=brand)
    import tempfile
    from pathlib import Path

    with tempfile.TemporaryDirectory() as td:
        out = Path(td) / "table_test.pptx"
        gen.generate(defn, out)
        return Presentation(str(out))


# ---------------------------------------------------------------------------
# TableStyle banding
# ---------------------------------------------------------------------------


class TestTableBanding:
    def test_banded_rows_default(self) -> None:
        elem = TableElement(
            type="table",
            rows=[
                [TableCell(text="H1"), TableCell(text="H2")],
                [TableCell(text="R1"), TableCell(text="R2")],
            ],
            table_style=TableStyle(banded_rows=True),
        )
        prs = _generate_table_deck(elem)
        table = prs.slides[0].shapes[-1].table
        assert table.horz_banding is True

    def test_banded_cols(self) -> None:
        elem = TableElement(
            type="table",
            rows=[
                [TableCell(text="H1"), TableCell(text="H2")],
                [TableCell(text="R1"), TableCell(text="R2")],
            ],
            table_style=TableStyle(banded_cols=True),
        )
        prs = _generate_table_deck(elem)
        table = prs.slides[0].shapes[-1].table
        assert table.vert_banding is True

    def test_first_col_bold(self) -> None:
        elem = TableElement(
            type="table",
            rows=[
                [TableCell(text="H1"), TableCell(text="H2")],
                [TableCell(text="R1"), TableCell(text="R2")],
            ],
            table_style=TableStyle(first_col_bold=True),
        )
        prs = _generate_table_deck(elem)
        table = prs.slides[0].shapes[-1].table
        assert table.first_col is True


# ---------------------------------------------------------------------------
# Cell margins
# ---------------------------------------------------------------------------


class TestCellMargins:
    def test_uniform_margin(self) -> None:
        elem = TableElement(
            type="table",
            rows=[
                [TableCell(text="H1"), TableCell(text="H2")],
                [TableCell(text="R1"), TableCell(text="R2")],
            ],
            table_style=TableStyle(cell_margin_pt=6.0),
        )
        prs = _generate_table_deck(elem)
        table = prs.slides[0].shapes[-1].table
        cell = table.cell(0, 0)
        # Margin is set in EMUs — Pt(6) = 76200 EMU
        expected = Pt(6.0)
        assert cell.margin_left == expected
        assert cell.margin_right == expected
        assert cell.margin_top == expected
        assert cell.margin_bottom == expected


# ---------------------------------------------------------------------------
# Vertical alignment
# ---------------------------------------------------------------------------


class TestVerticalAlignment:
    def test_top_alignment(self) -> None:
        elem = TableElement(
            type="table",
            rows=[
                [TableCell(text="Top", vertical_align="top")],
            ],
            header_row=False,
        )
        prs = _generate_table_deck(elem)
        table = prs.slides[0].shapes[-1].table
        cell = table.cell(0, 0)
        assert cell.vertical_anchor == MSO_ANCHOR.TOP

    def test_middle_alignment(self) -> None:
        elem = TableElement(
            type="table",
            rows=[
                [TableCell(text="Middle", vertical_align="middle")],
            ],
            header_row=False,
        )
        prs = _generate_table_deck(elem)
        table = prs.slides[0].shapes[-1].table
        cell = table.cell(0, 0)
        assert cell.vertical_anchor == MSO_ANCHOR.MIDDLE

    def test_bottom_alignment(self) -> None:
        elem = TableElement(
            type="table",
            rows=[
                [TableCell(text="Bottom", vertical_align="bottom")],
            ],
            header_row=False,
        )
        prs = _generate_table_deck(elem)
        table = prs.slides[0].shapes[-1].table
        cell = table.cell(0, 0)
        assert cell.vertical_anchor == MSO_ANCHOR.BOTTOM


# ---------------------------------------------------------------------------
# Cell merge regression
# ---------------------------------------------------------------------------


class TestCellMergeRegression:
    def test_col_span_still_works(self) -> None:
        elem = TableElement(
            type="table",
            rows=[
                [TableCell(text="Merged", col_span=2), TableCell(text="")],
                [TableCell(text="A"), TableCell(text="B")],
            ],
        )
        prs = _generate_table_deck(elem)
        table = prs.slides[0].shapes[-1].table
        # The merged cell should span 2 columns
        cell = table.cell(0, 0)
        assert cell.is_merge_origin is True
