"""Run one ADE parse end to end: submit, write artifacts, summarize.

`run_parse` takes a source PDF or image (local path or ``s3://`` URI), an
output destination (local directory or ``s3://`` prefix), a model name, and
an optional 1-based page number. It parses the document through ADE, writes
the artifacts through the same output contract the other extraction routines
honor, and returns a run summary with the credit usage the platform reported.

Artifacts per run: ``<base>.ade.json`` (raw parse response), ``<base>.ade.md``
(the parse markdown), and ``<base>.ade.complete.json`` written strictly last as
the completion marker.
"""

from __future__ import annotations

import json
import tempfile
from dataclasses import dataclass, field
from pathlib import Path
from typing import Optional

from loguru import logger

from quber.files.cache import resolve_document
from quber.files.output import output_sink, write_completion_marker
from quber.files.pdf import slice_page
from quber.providers.landing.client import DEFAULT_MODEL, parse_document


@dataclass
class RunSummary:
    """What one ADE run produced, for the CLI to print and callers to log."""

    base: str
    pages: Optional[int]
    #: Credits the platform billed for the run (v2 bills fractional credits).
    credits: Optional[float]
    model_version: Optional[str]
    artifacts: list[str] = field(default_factory=list)


def run_parse(
    source: str,
    output_dir: str = "output",
    model: str = DEFAULT_MODEL,
    page: Optional[int] = None,
) -> RunSummary:
    """Parse ``source`` through ADE and write artifacts to ``output_dir``."""
    local = resolve_document(source)
    base = local.stem
    if page is not None:
        base = f"{base}.p{page}"

    with tempfile.TemporaryDirectory(prefix="quber-ade-") as tmp:
        submitted = local
        if page is not None:
            submitted = slice_page(local, page, Path(tmp) / f"{base}.pdf")
        doc = parse_document(submitted, model=model)

    meta = doc.get("metadata") or {}

    # v1 metadata reports credit_usage and version; v2 reports
    # billing.total_credits and model_version.
    credits = meta.get("credit_usage")
    if credits is None:
        credits = (meta.get("billing") or {}).get("total_credits")
    summary = RunSummary(
        base=base,
        pages=meta.get("page_count"),
        credits=credits,
        model_version=meta.get("version") or meta.get("model_version"),
    )

    with output_sink(output_dir) as out:
        json_path = out / f"{base}.ade.json"
        json_path.write_text(json.dumps(doc, indent=1), encoding="utf-8")
        md_path = out / f"{base}.ade.md"
        md_path.write_text(doc.get("markdown") or "", encoding="utf-8")
        summary.artifacts = [json_path.name, md_path.name]

    write_completion_marker(
        output_dir,
        f"{base}.ade.complete.json",
        {
            "artifacts": summary.artifacts,
            "page_count": summary.pages,
            "credit_usage": summary.credits,
            "version": summary.model_version,
            "job_id": meta.get("job_id"),
        },
    )
    logger.info(
        "ADE run complete: base={} pages={} credits={}",
        summary.base,
        summary.pages,
        summary.credits,
    )
    return summary
