""" a panflute filter to format Span element
representations of RawInline elements

The :py:mod:`ipypublish.filters_pandoc.prepare_raw` filter should be run
first to access the functionality below:

"""
import itertools

# from textwrap import fill as textwrap

from panflute import Element, Doc, Span  # noqa: F401
import panflute as pf

from ipypublish.filters_pandoc.definitions import (
    CONVERTED_OTHER_CLASS,
    CONVERTED_DIRECTIVE_CLASS,
    IPUB_META_ROUTE,
)


def process_raw_spans(container, doc):
    # type: (Span, Doc) -> Element
    if not isinstance(container, (pf.Span, pf.Div)):
        return None

    hide_raw = doc.get_metadata(IPUB_META_ROUTE + ".hide_raw", False)

    if CONVERTED_OTHER_CLASS in container.classes and isinstance(container, pf.Span):
        if doc.format == "rst" and container.attributes["format"] == "latex":
            if container.attributes["tag"] in ["todo"]:
                return pf.Str(
                    "\n\n.. {}:: {}\n\n".format(
                        container.attributes["tag"], container.attributes["content"]
                    )
                )
            if container.attributes["tag"] == "ensuremath":
                return pf.RawInline(
                    ":math:`{}`".format(container.attributes["content"]), format="rst"
                )

        return pf.RawInline(
            container.attributes.get("original"), format=container.attributes["format"]
        )

    if CONVERTED_DIRECTIVE_CLASS in container.classes and isinstance(container, pf.Div):
        # convert the directive head, which will be e.g.
        # Para(Str(..) Space Str(toctree::) SoftBreak Str(:maxdepth:) Space Str(2) SoftBreak Str(:numbered:))  # noqa
        # we need to spilt on the soft breaks,
        # place them on a new line and re-indent them

        if doc.format in ("rst"):

            # split into lines by soft breaks
            header_lines = [
                list(y)
                for x, y in itertools.groupby(
                    container.content[0].content, lambda z: isinstance(z, pf.SoftBreak)
                )
                if not x
            ]

            # wrap each line in a Para and convert block with pandoc
            head_doc = pf.Doc(*[pf.Para(*l) for l in header_lines])
            head_doc.api_version = doc.api_version
            head_str = pf.convert_text(
                head_doc, input_format="panflute", output_format=doc.format
            )
            # remove blank lines and indent
            head_str = head_str.replace("\n\n", "\n    ") + "\n\n"
            head_block = pf.RawBlock(head_str, format=doc.format)

            if len(container.content) == 1:
                return head_block

            # split into lines by soft breaks, we use indicators to tell
            # us where to indent in the converted text
            body_blocks = []