"""The document an answer is about, stated to the model.

A chunk carries its page heading and its table's caption, and a table's header
rows usually carry the period. A chart on a slide carries none of that: the
deck's date is on its cover, not on the slide. Handed a chart alone, the
answer model refuses to date it, which is the right reading of its own rules.
The period is a property of the document, and the documents table already
holds it, so the route states it ahead of the context on every request.

The header is data the route knows, not prompt text: it is built from the
document row and prepended to the user message, and the system prompt does not
change.
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Mapping, Optional


@dataclass(frozen=True)
class DocumentIdentity:
    title: Optional[str] = None
    issuer: Optional[str] = None
    form: Optional[str] = None
    period: Optional[str] = None
    year: Optional[int] = None

    @classmethod
    def from_row(cls, row: Mapping[str, Any]) -> "DocumentIdentity":
        """From a documents-table row as the routes carry it (`_doc_dict`)."""
        return cls(
            title=row.get("title"),
            issuer=row.get("folder"),
            form=row.get("filing_type"),
            period=row.get("period"),
            year=row.get("year"),
        )

    def header(self) -> str:
        """The block that opens the user message. Fields the row lacks are left out."""
        period = " ".join(str(p) for p in (self.period, self.year) if p)
        fields = [
            ("Title", self.title),
            ("Issuer", self.issuer),
            ("Form", self.form),
            ("Period", period or None),
        ]
        lines = ["Document"] + [f"  {name}:  {value}" for name, value in fields if value]
        lines.append(
            "Every figure in the context below is from this document unless a chunk states another period."
        )
        return "\n".join(lines)


def with_document(prompt: str, document: Optional[DocumentIdentity]) -> str:
    """The prompt with the document stated first, or unchanged when none is known."""
    if document is None:
        return prompt
    return f"{document.header()}\n\n{prompt}"
