import json
from pathlib import Path

import pytest
from pymultirole_plugins.v1.schema import Document, DocumentList

from pysegmenters_md_splitter.md_splitter import (
    ExperimentalMarkdownSyntaxTextSplitter,
    MarkdownSplitterParameters,
    MarkdownSplitterSegmenter,
)


def test_md_splitter():
    testdir = Path(__file__).parent
    source = Path(testdir, "data/bigsegments.json")
    with source.open("r") as fin:
        jdocs = json.load(fin)
    original_docs = [Document(**jdoc) for jdoc in jdocs]
    model = MarkdownSplitterSegmenter.get_model()
    model_class = model.model_construct().__class__
    assert model_class == MarkdownSplitterParameters
    segmenter = MarkdownSplitterSegmenter()
    parameters = MarkdownSplitterParameters()
    docs: list[Document] = segmenter.segment(original_docs, parameters)
    assert len(docs) == 1
    doc0 = docs[0]
    assert len(doc0.sentences) == 115
    for sent in doc0.sentences:
        ctext = doc0.text[sent.start : sent.end]
        print("===========================================================")
        print(ctext)

    dl = DocumentList(root=docs)
    result = Path(testdir, "data/bigsegments_segmented.json")
    with result.open("w") as fout:
        print(dl.model_dump_json(exclude_none=True, exclude_unset=True, indent=2), file=fout)


@pytest.mark.skip(reason="misstitle scenario not yet supported: same-depth headers collapse parent sections")
def test_misstitle():
    # This test documents a known limitation of the splitter with malformed heading hierarchies,
    # common in documents converted from PDF.
    #
    # The document jumps from h1 (#) straight to h3 (###), skipping h2:
    #
    #   # VE-4200 Hybrid Grid+ – Product Documentation
    #   ### 1. Introduction          <- empty section, no content
    #   ### 1.1 Product Overview     <- first section with actual content
    #   The VE-4200 Hybrid Grid+ is...
    #
    # Desired behaviour: the first sentence (under 1.1) should carry "1. Introduction"
    # in its breadcrumb, since it conceptually belongs to that parent section:
    #   "VE-4200 Hybrid Grid+ / 1. Introduction / 1.1 Product Overview"
    #
    # Actual behaviour: because both headers are h3 (same depth), _resolve_header_stack
    # treats them as siblings and replaces "1. Introduction" with "1.1 Product Overview":
    #   "VE-4200 Hybrid Grid+ / 1.1 Product Overview"
    #
    # A fix would require either:
    # - Treating empty/title-only headers as persistent parent buckets regardless of depth, or
    # - Using numbering-based hierarchy (1. is parent of 1.1) instead of # depth alone.
    testdir = Path(__file__).parent
    source = Path(testdir, "data/misstitle.json")
    with source.open("r") as fin:
        jdoc = json.load(fin)
    original_doc = Document(**jdoc)
    model = MarkdownSplitterSegmenter.get_model()
    model_class = model.model_construct().__class__
    assert model_class == MarkdownSplitterParameters
    segmenter = MarkdownSplitterSegmenter()
    parameters = MarkdownSplitterParameters()
    docs: list[Document] = segmenter.segment([original_doc], parameters)
    assert len(docs) == 1
    doc0 = docs[0]
    assert len(doc0.sentences) == 14
    sent0 = doc0.sentences[0]
    assert "1. Introduction" in sent0.metadata["Headers"]


def test_splitter():
    text = """[^0] [^0]: *Average from January to December 2024

```
Non-binding

```
** Topics = last version articles
** Actualisations = all versions articles
```
# AFP STORIES IN ARABIC

## Coverage
"""
    splitter = ExperimentalMarkdownSyntaxTextSplitter(headers_to_split_on=-1, strip_headers=False)
    chunks = splitter.split_text(text)
    ctext = ""
    for chunk in chunks:
        ctext += chunk.text
        cmetas = {k: v for k, v in chunk.metadata.items() if isinstance(k, int)}
        headers = [v for k, v in sorted(cmetas.items())]
        smetadata = {}
        if headers:
            smetadata["Headers"] = " / ".join(headers)
    assert ctext == text


def test_splitter_file():
    testdir = Path(__file__).parent
    source = Path(testdir, "data/Hello all2.md")
    with source.open("r") as fin:
        text = fin.read()
    splitter = ExperimentalMarkdownSyntaxTextSplitter(headers_to_split_on=-1, strip_headers=False)
    chunks = splitter.split_text(text)
    ctext = ""
    for chunk in chunks:
        ctext += chunk.text
        cmetas = {k: v for k, v in chunk.metadata.items() if isinstance(k, int)}
        headers = [v for k, v in sorted(cmetas.items())]
        smetadata = {}
        if headers:
            smetadata["Headers"] = " / ".join(headers)
    assert ctext == text
