"""Tests for WordRenderer — Markdown → .docx mapping (U2)."""

from __future__ import annotations

from pathlib import Path

from docx import Document

from agentkit.documents.renderers.word_renderer import WordRenderer


def _render(markdown: str, tmp_path: Path) -> Path:
    """Render markdown to a temp .docx and return the path."""
    out = tmp_path / "test.docx"
    WordRenderer().render(markdown, out)
    return out


def _read_paragraphs(path: Path) -> list[str]:
    """Return all paragraph texts from a .docx."""
    doc = Document(str(path))
    return [p.text for p in doc.paragraphs]


def test_heading_levels(tmp_path: Path) -> None:
    """# / ## / ### map to heading levels 1/2/3."""
    md = "# Title\n## Subtitle\n### Section\n"
    path = _render(md, tmp_path)
    doc = Document(str(path))
    headings = [(p.style.name, p.text) for p in doc.paragraphs if p.text]
    assert ("Heading 1", "Title") in headings
    assert ("Heading 2", "Subtitle") in headings
    assert ("Heading 3", "Section") in headings


def test_paragraphs(tmp_path: Path) -> None:
    """Plain text lines become paragraphs."""
    md = "First paragraph.\n\nSecond paragraph.\n"
    path = _render(md, tmp_path)
    texts = _read_paragraphs(path)
    assert "First paragraph." in texts
    assert "Second paragraph." in texts


def test_bullet_list(tmp_path: Path) -> None:
    """Bullet items use List Bullet style."""
    md = "- Apple\n- Banana\n- Cherry\n"
    path = _render(md, tmp_path)
    doc = Document(str(path))
    bullets = [p for p in doc.paragraphs if p.style.name == "List Bullet"]
    assert len(bullets) == 3
    assert bullets[0].text == "Apple"
    assert bullets[1].text == "Banana"
    assert bullets[2].text == "Cherry"


def test_numbered_list(tmp_path: Path) -> None:
    """Numbered items use List Number style."""
    md = "1. First\n2. Second\n3. Third\n"
    path = _render(md, tmp_path)
    doc = Document(str(path))
    numbers = [p for p in doc.paragraphs if p.style.name == "List Number"]
    assert len(numbers) == 3
    assert numbers[0].text == "First"
    assert numbers[1].text == "Second"


def test_table(tmp_path: Path) -> None:
    """GFM table maps to a docx table with correct cells."""
    md = "| Name | Age |\n| --- | --- |\n| Alice | 30 |\n| Bob | 25 |\n"
    path = _render(md, tmp_path)
    doc = Document(str(path))
    assert len(doc.tables) == 1
    table = doc.tables[0]
    # 3 rows (header + 2 data), 2 cols
    assert len(table.rows) == 3
    assert len(table.columns) == 2
    assert table.cell(0, 0).text == "Name"
    assert table.cell(0, 1).text == "Age"
    assert table.cell(1, 0).text == "Alice"
    assert table.cell(2, 1).text == "25"


def test_bold_inline(tmp_path: Path) -> None:
    """**bold** produces a bold run."""
    md = "This has **bold** text.\n"
    path = _render(md, tmp_path)
    doc = Document(str(path))
    para = doc.paragraphs[0]
    bold_runs = [r for r in para.runs if r.bold]
    assert len(bold_runs) == 1
    assert bold_runs[0].text == "bold"


def test_italic_inline(tmp_path: Path) -> None:
    """*italic* produces an italic run."""
    md = "This has *italic* text.\n"
    path = _render(md, tmp_path)
    doc = Document(str(path))
    para = doc.paragraphs[0]
    italic_runs = [r for r in para.runs if r.italic]
    assert len(italic_runs) == 1
    assert italic_runs[0].text == "italic"


def test_empty_markdown(tmp_path: Path) -> None:
    """Empty Markdown produces a valid (empty) document."""
    path = _render("", tmp_path)
    assert path.exists()
    doc = Document(str(path))
    # No paragraphs with text
    assert all(not p.text for p in doc.paragraphs)


def test_mixed_content(tmp_path: Path) -> None:
    """Heading + paragraph + list + table renders without error."""
    md = """# Report

This is the intro.

- Point one
- Point two

| Col A | Col B |
| ----- | ----- |
| 1     | 2     |

Final paragraph.
"""
    path = _render(md, tmp_path)
    assert path.exists()
    doc = Document(str(path))
    # Should have at least one heading, one table, two bullet items
    headings = [p for p in doc.paragraphs if p.style.name.startswith("Heading")]
    assert len(headings) >= 1
    assert len(doc.tables) == 1
    bullets = [p for p in doc.paragraphs if p.style.name == "List Bullet"]
    assert len(bullets) == 2


def test_chinese_text(tmp_path: Path) -> None:
    """Chinese characters render correctly in paragraphs and headings."""
    md = "# 中文标题\n\n这是中文段落。\n"
    path = _render(md, tmp_path)
    texts = _read_paragraphs(path)
    assert "中文标题" in texts
    assert "这是中文段落。" in texts
