"""Auditor: scans the repo, produces evidence.md, task_contract.md, and summary.md."""

from __future__ import annotations

from milco.core.run_context import RunContext
from milco.core.artifacts import write_artifact, ensure_all_artifacts_exist
from milco.core.contract import load_and_validate
from milco.tools.fs_tools import scan_repo


def run_audit(ctx: RunContext) -> dict:
    """Execute the audit phase. Returns a status dict."""
    ctx.ensure_run_dir()
    status: dict = {"phase": "audit", "run_id": ctx.run_id, "errors": []}

    # --- task_contract.md ---
    if ctx.contract_path:
        try:
            text, missing = load_and_validate(ctx.contract_path)
            if missing:
                status["errors"].append(f"Contract missing sections: {missing}")
                write_artifact(
                    ctx,
                    "task_contract.md",
                    f"# INVALID CONTRACT\n\nMissing: {missing}\n\n{text}",
                )
            else:
                write_artifact(ctx, "task_contract.md", text)
        except FileNotFoundError as exc:
            status["errors"].append(str(exc))
            write_artifact(ctx, "task_contract.md", f"# Contract not found\n\n{exc}\n")
    else:
        write_artifact(
            ctx,
            "task_contract.md",
            "# No contract provided\n\n_Pass --contract to supply one._\n",
        )

    # --- task type validation ---
    if ctx.task_type:
        from milco.tasks.registry import get_task
        import milco.tasks.map_gen  # noqa: F401

        if get_task(ctx.task_type) is None:
            status["errors"].append(f"Unknown task type: '{ctx.task_type}'")

    # --- LLM reachability ---
    if ctx.llm is not None:
        if not ctx.llm.ping():
            status["errors"].append(
                f"LLM provider '{ctx.llm.name}' is not reachable. Check milco.toml and ensure the service is running."
            )

    # --- evidence.md ---
    repo_map = scan_repo(ctx.repo_root)
    evidence_lines = [
        "# Evidence\n",
        f"Repo root: `{repo_map['repo_root']}`\n",
        f"Total files: {repo_map['total_files']}",
        f"Total directories: {repo_map['total_directories']}",
        f"Python files: {repo_map['python_file_count']}\n",
        "## File listing\n",
    ]
    for f in repo_map["files"]:
        evidence_lines.append(f"- `{f}`")
    evidence_text = "\n".join(evidence_lines) + "\n"
    write_artifact(ctx, "evidence.md", evidence_text)

    # --- summary.md with plan ---
    summary_lines = [
        "# Audit Summary\n",
        f"Run ID: `{ctx.run_id}`",
        f"Mode: {'apply' if ctx.apply_mode else 'dry-run'}\n",
        "## Plan\n",
        "### Step 1: Scan repo\n",
        "- tool: fs_tools.scan_repo\n",
        "### Step 2: Generate map.json diff\n",
        "- tool: fixer.generate_map_diff\n",
        "### Step 3: Run gates\n",
        "- tool: gates.run_all_gates\n",
    ]
    if status["errors"]:
        summary_lines.append("\n## Errors\n")
        for e in status["errors"]:
            summary_lines.append(f"- {e}")
    write_artifact(ctx, "summary.md", "\n".join(summary_lines) + "\n")

    ensure_all_artifacts_exist(ctx)
    status["success"] = len(status["errors"]) == 0
    return status
