#!/usr/bin/env python3
"""Render a 1C task change proposal JSON as a compact Markdown report."""

from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import Any


def load_json(path: Path) -> dict[str, Any]:
    return json.loads(path.read_text(encoding="utf-8-sig"))


def line(text: str = "") -> str:
    return text.rstrip() + "\n"


def bullet(text: str) -> str:
    return f"- {text}\n"


def fmt_origin(origin: dict[str, Any] | None) -> str:
    if not origin:
        return ""
    if origin.get("extension"):
        return f"{origin.get('layer')}:{origin.get('extension')}"
    return str(origin.get("layer") or "")


def fmt_path(path: str | None, line_no: Any = None) -> str:
    if not path:
        return ""
    suffix = f":{line_no}" if line_no else ""
    return f"`{path}{suffix}`"


def render_target(target: dict[str, Any]) -> str:
    path = target.get("path") or target.get("module_path")
    bits = [str(target.get("kind") or ""), str(target.get("name") or "")]
    origin = fmt_origin(target.get("origin"))
    if origin:
        bits.append(f"({origin})")
    rendered = " ".join(bit for bit in bits if bit)
    if path:
        rendered += f" -> {fmt_path(path, target.get('line'))}"
    return rendered


def render_proposal(proposal: dict[str, Any], index: int) -> str:
    out = ""
    obj = proposal.get("object") or {}
    out += line(f"## Proposal {index}: {obj.get('kind')}.{obj.get('name')}")
    if obj.get("synonym"):
        out += line(f"Synonym: {obj.get('synonym')}")
    out += line()
    strategy = proposal.get("write_strategy") or {}
    out += line("### Strategy")
    out += bullet(f"Mode: `{strategy.get('mode')}`")
    out += bullet(f"Preferred extension: `{strategy.get('preferred_extension')}`")
    out += bullet(f"Reason: {strategy.get('reason')}")
    out += line()

    state = proposal.get("existing_state") or {}
    commands = state.get("found_form_commands_or_items") or []
    attrs = state.get("found_metadata_attributes") or []
    code_hits = state.get("found_code_hits") or []
    if commands:
        out += line("### Existing Form Commands/Items")
        for row in commands[:10]:
            out += bullet(
                f"{row.get('area')} `{row.get('name')}` on `{row.get('form')}` "
                f"({fmt_origin(row.get('origin'))}) {fmt_path(row.get('path'), row.get('line'))}"
            )
        out += line()
    if attrs:
        out += line("### Related Metadata Attributes")
        for row in attrs[:10]:
            out += bullet(f"`{row.get('name')}` ({fmt_origin(row.get('origin'))})")
        out += line()
    if code_hits:
        out += line("### Code Hits")
        for row in code_hits[:12]:
            out += bullet(f"`{row.get('name')}` ({fmt_origin(row.get('origin'))}) {fmt_path(row.get('path'), row.get('line'))}")
        out += line()

    policy = proposal.get("target_policy") or {}
    write_candidates = policy.get("write_candidates") or []
    references = policy.get("read_only_reference_files") or []
    out += line("### Write Candidates")
    if write_candidates:
        for target in write_candidates[:20]:
            out += bullet(render_target(target))
    else:
        out += bullet("No write candidate selected.")
    out += line()
    out += line("### Read-Only References")
    for target in references[:20]:
        out += bullet(render_target(target))
    if len(references) > 20:
        out += bullet(f"... {len(references) - 20} more")
    out += line()

    out += line("### Implementation Steps")
    for step in proposal.get("implementation_steps") or []:
        out += bullet(f"{step.get('order')}. `{step.get('action')}` - {step.get('purpose') or ''}")
    out += line()
    out += line("### Validation")
    for check in proposal.get("validation_checks") or []:
        out += bullet(f"`{check.get('name')}` - {check.get('description')}")
    questions = proposal.get("open_questions") or []
    if questions:
        out += line()
        out += line("### Open Questions")
        for question in questions:
            out += bullet(question)
    return out


def render(data: dict[str, Any]) -> str:
    out = ""
    out += line("# 1C Task Change Proposal")
    out += line()
    out += line(f"Task: {((data.get('task') or {}).get('text') or '').strip()}")
    out += line(f"Schema: `{data.get('schema')}`")
    out += line(f"View: `{data.get('view')}`")
    safety = data.get("safety") or {}
    out += line(f"Safety: `{safety.get('mode')}`, `{safety.get('write_status')}`")
    out += line()
    for idx, proposal in enumerate(data.get("proposals") or [], start=1):
        out += render_proposal(proposal, idx)
        out += line()
    return out


def main() -> int:
    parser = argparse.ArgumentParser(description="Render 1C task proposal Markdown.")
    parser.add_argument("--proposal", type=Path, required=True)
    parser.add_argument("--output", type=Path)
    args = parser.parse_args()

    markdown = render(load_json(args.proposal))
    if args.output:
        args.output.parent.mkdir(parents=True, exist_ok=True)
        args.output.write_text(markdown, encoding="utf-8")
        print(json.dumps({"output": str(args.output)}, ensure_ascii=False))
    else:
        print(markdown)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
