from __future__ import annotations


def _build_docx_common_system_prompt() -> str:
    return """
You generate YAML only. Produce a self-contained semantic document specification that will be rendered into an
editable Microsoft Word DOCX file.

Top-level schema:
- schema_version: 1
- document: mapping
- blocks: ordered list of semantic content blocks

Document mapping:
- title: required quoted string
- subtitle: optional quoted string
- author: optional quoted string; omit unless supplied by the user
- date: optional quoted string; omit unless supplied by the user
- subject: optional quoted string

Every block requires:
- id: unique descriptive lowercase diagnostic identifier using only letters, digits, underscores, or hyphens
- type: one of heading, paragraph, list, table, callout, quote, image, page_break

Block schemas:
- heading: id, type, level (1 to 3), text
- paragraph with plain text: id, type, text
- paragraph with rich text: id, type, runs; each run has text and optional bold, italic, underline booleans
- list: id, type, style (bullet or numbered), items; each item has text and level (0 to 2)
- table: id, type, optional title, columns, rows, optional column_widths, optional source
- callout: id, type, optional label, text
- quote: id, type, text, optional attribution
- image: id, type, asset_id, optional caption, optional width (small, medium, large, or full), optional alignment
  (left, center, or right)
- page_break: id, type

Valid abbreviated document example:
schema_version: 1
document:
  title: "Operations Readiness Brief"
  subtitle: "Launch decision and next actions"
blocks:
  - id: executive-summary
    type: heading
    level: 1
    text: "Executive summary"
  - id: summary-text
    type: paragraph
    text: "The launch is viable once the remaining controls have accountable owners."
  - id: priority-actions
    type: list
    style: numbered
    items:
      - text: "Confirm the incident commander."
        level: 0
      - text: "Publish the escalation matrix."
        level: 0
  - id: readiness-controls
    type: table
    title: "Open controls"
    columns: ["Control", "Owner", "Status"]
    rows:
      - ["Escalation matrix", "Support lead", "In progress"]

Core rules:
- Unless the user asks otherwise, produce a readable, structured, professional document fitting the requested type.
- The title belongs in document.title; do not repeat it as the first heading.
- Build a flow-based business document, not a slide deck or desktop-publishing layout.
- Use heading levels sequentially. Never jump from level 1 directly to level 3.
- Use paragraph.text for plain paragraphs or paragraph.runs for rich text, never both.
- Use rich text sparingly and only for meaningful emphasis.
- Lists must use structured list items. Do not type bullet glyphs, hyphens, or manual item numbers into paragraph text.
- The first list item must be level 0 and nesting may increase by at most one level at a time.
- Tables are only for true row/column comparison or lookup data. Every row must match the column count.
- column_widths are relative positive weights, not inches or percentages. Omit them when the best widths are unclear.
- Use callouts for a recommendation, decision, warning, or key takeaway; keep them concise.
- Use quotes only for supplied or clearly attributed material. Do not fabricate quotations.
- Use image blocks only when exact image asset ids are provided in source artifact context. Never invent asset ids.
- Image captions are literal visible text. Include any requested figure label or number in the caption itself.
- Image width defaults to large and alignment defaults to center. Images remain in normal document flow.
- Use page breaks sparingly and never at the beginning or end.
- Do not include unsupported blocks such as charts, text boxes, HTML, raw OOXML, footnotes, or a generated TOC.
- Honor the requested language and tone.
- Do not invent an author or date when the user did not provide one.
- Do not invent facts, metrics, citations, or sources. When source records are provided, use them faithfully.

YAML safety rules:
- Quote every free-text value, including titles, prose, labels, dates, numeric-looking strings, and yes/no-like words.
- Use block scalar `|` for multi-line prose when needed.
- Do not use anchors, aliases, merge keys, custom tags, or duplicate mapping keys.
- Do not emit Markdown fences or explanatory prose.

Content quality:
- Each section must teach, explain, compare, recommend, or instruct something concrete.
- Prefer short, readable paragraphs over walls of text.
- Use varied form factors only when they match the reading task; do not turn normal prose into tables.
- Keep table cells concise enough to read in Word.
""".strip()


def build_docx_system_prompt() -> str:
    return f"""
{_build_docx_common_system_prompt()}

Generation rules:
- Choose a section structure appropriate to the requested document type and length.
- Cover every explicit content requirement from the user request.
- Use level-1 headings for meaningful body sections, but do not force unnecessary sections into short documents.
- End with a practical conclusion, recommendation, or next step when appropriate to the request.

Return YAML only.
""".strip()


def build_docx_revision_system_prompt() -> str:
    return f"""
{_build_docx_common_system_prompt()}

Revision rules:
- Treat the source document specification as authoritative.
- Apply only the requested changes and return one complete revised document specification.
- Preserve unmentioned document metadata, content, block order, block types, list structure, tables, image blocks,
  and rich-text runs.
- Do not add sections, conclusions, examples, facts, or stylistic rewrites unless the revision request requires them.
- Existing block ids are diagnostic anchors, not cross-revision identities. Preserve them when convenient, but keep all
  ids unique within the returned specification.

Return YAML only.
""".strip()


def build_docx_document_user_prompt(user_prompt: str) -> str:
    return f"""
Generate the complete YAML document specification for the user request below.

User request:
{user_prompt}

Return YAML only. Organize the content into a coherent structure appropriate to the request.
""".strip()


def build_docx_revision_user_prompt(*, source_document_yaml: str, revision_instructions: str) -> str:
    return f"""
Revise the source document specification according to the user's instructions.
Return the complete revised document specification as YAML only.

Revision instructions:
{revision_instructions}

Source document specification:
{source_document_yaml}
""".strip()


def build_docx_repair_prompt(
    *,
    user_prompt: str,
    current_document_yaml: str,
    validation_error: str,
    quality_feedback: str | None,
    attempt: int,
    max_attempts: int,
) -> str:
    quality_section = (
        f"\nQuality feedback:\n{quality_feedback}\n" if quality_feedback and quality_feedback.strip() else ""
    )
    return f"""
Repair the YAML document specification. Return the full corrected document specification as YAML only.
Preserve valid content and the user's intent while fixing the reported issues.

Attempt: {attempt}/{max_attempts}

User request:
{user_prompt}

Validation error:
{validation_error}
{quality_section}
Current document specification:
{current_document_yaml}
""".strip()


def build_docx_revision_repair_prompt(
    *,
    source_document_yaml: str,
    revision_instructions: str,
    current_document_yaml: str,
    validation_error: str,
    quality_feedback: str | None,
    attempt: int,
    max_attempts: int,
) -> str:
    quality_section = (
        f"\nQuality feedback:\n{quality_feedback}\n" if quality_feedback and quality_feedback.strip() else ""
    )
    return f"""
Repair the revised YAML document specification. Return the complete corrected specification as YAML only.
Preserve the requested changes and all unrelated source content while fixing only the reported issues.

Attempt: {attempt}/{max_attempts}

Revision instructions:
{revision_instructions}

Validation error:
{validation_error}
{quality_section}
Original source document specification:
{source_document_yaml}

Current revised document specification:
{current_document_yaml}
""".strip()


def build_docx_revision_syntax_repair_prompt(
    *,
    source_document_yaml: str,
    revision_instructions: str,
    current_document_yaml: str,
    syntax_error: str,
    attempt: int,
    max_attempts: int,
) -> str:
    return f"""
Repair only the YAML syntax of the revised document specification. Return the complete corrected YAML only.
Do not change content, structure, or the requested revision beyond what is necessary to produce valid YAML.

Attempt: {attempt}/{max_attempts}

Revision instructions:
{revision_instructions}

Syntax error:
{syntax_error}

Original source document specification:
{source_document_yaml}

Current revised document specification:
{current_document_yaml}
""".strip()
