"""pipeline.py — the Efferent Multimodal Projector, top level.

    geometry region + surface/format spec
        -> PLAN     (manifold -> document skeleton/DAG)
        -> REALIZE  (proven realizer, sentence -> passage, each section faithful)
        -> COHERE   (document-level flow / transitions, not stitched sentences)
        -> EMIT     (pluggable SurfaceProjector -> the target surface)

THE SURFACE IS A PARAMETER. ``project(...)`` builds the geometry-carrying
DocumentIR once, then hands it to whichever surface projector the caller named.
Markdown, docx, and midi (music) are all the SAME IR emitted differently. That
is the efferent multimodal projector: geometry -> any surface.
"""
from __future__ import annotations

import os
import sys

_HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, _HERE)
sys.path.insert(0, os.path.join(_HERE, "projectors"))

from cohere import cohere_document  # noqa: E402
from document_ir import DocumentIR  # noqa: E402
from geometry import Region, load_region  # noqa: E402
from plan import plan_document  # noqa: E402
from realize import realize_document  # noqa: E402

# registering the projectors (import for side-effect: each self-registers)
import projectors.markdown  # noqa: E402,F401
import projectors.docx  # noqa: E402,F401
import projectors.midi  # noqa: E402,F401
import projectors.seams  # noqa: E402,F401
from projectors.base import available_surfaces, get_projector  # noqa: E402


def build_ir(seed_terms, *, title: str, subtitle: str = "",
             format_spec: dict | None = None,
             region: Region | None = None,
             max_sections: int = 8, conf_floor: float = 0.55) -> DocumentIR:
    """geometry -> PLAN -> REALIZE -> COHERE = the surface-neutral DocumentIR."""
    region = region or load_region(seed_terms)
    doc = plan_document(region, title=title, subtitle=subtitle,
                        format_spec=format_spec or {},
                        conf_floor=conf_floor, max_sections=max_sections)
    doc = realize_document(doc)
    doc = cohere_document(doc)
    return doc


def emit(doc: DocumentIR, surface: str) -> bytes:
    """EMIT: project the built IR onto one surface (surface = a parameter)."""
    return get_projector(surface).project(doc)


def project(seed_terms, *, surface: str, title: str, subtitle: str = "",
            format_spec: dict | None = None, region: Region | None = None,
            max_sections: int = 8) -> tuple[DocumentIR, bytes]:
    """The full efferent projection: geometry + surface -> (IR, bytes)."""
    doc = build_ir(seed_terms, title=title, subtitle=subtitle,
                   format_spec=format_spec, region=region,
                   max_sections=max_sections)
    return doc, emit(doc, surface)


__all__ = ["build_ir", "emit", "project", "available_surfaces",
           "get_projector", "load_region", "DocumentIR"]
