"""Run all recommended extractors and merge results into a single JSON output."""

import argparse
import json
import sys

from detect import analyze
from extractors.native import extract as native_extract
from extractors.scanned import extract as scanned_extract
from extractors.mixed import extract as mixed_extract
from extractors.tables import extract as tables_extract
from extractors.images import extract as images_extract
from extractors.forms import extract as forms_extract
from extractors.epub import extract as epub_extract
from extractors.ebook import extract as ebook_extract

EXTRACTOR_MAP = {
    "native": ("native", native_extract),
    "scanned": ("scanned", scanned_extract),
    "mixed": ("mixed", mixed_extract),
    "tables": ("tables", tables_extract),
    "images": ("images", images_extract),
    "forms": ("forms", forms_extract),
    "epub": ("epub", epub_extract),
    "ebook": ("ebook", ebook_extract),
}


def run_ensemble(pdf_path: str, extractors: list[str] | None = None) -> dict:
    """Run specified extractors (or auto-detect) and merge results.

    Returns a dict with analysis metadata and each extractor's output.
    """
    analysis = analyze(pdf_path)

    if extractors is None:
        extractors = analysis["recommended_extractors"]

    results = {"analysis": analysis, "extractors": {}}

    for name in extractors:
        if name not in EXTRACTOR_MAP:
            results["extractors"][name] = {"error": f"Unknown extractor: {name}"}
            continue

        label, extract_fn = EXTRACTOR_MAP[name]
        try:
            data = extract_fn(pdf_path)
            results["extractors"][label] = data
        except Exception as e:
            results["extractors"][label] = {"error": str(e)}

    return results


def main():
    parser = argparse.ArgumentParser(description="Run ensemble PDF extraction")
    parser.add_argument("pdf", help="Path to input PDF")
    parser.add_argument("output", nargs="?", default=None, help="Output file path")
    parser.add_argument("--extractors", nargs="+",
                        choices=["native", "scanned", "mixed", "tables", "images", "forms", "epub", "ebook"],
                        help="Specific extractors to run (default: auto-detect)")
    args = parser.parse_args()

    results = run_ensemble(args.pdf, extractors=args.extractors)

    output = json.dumps(results, indent=2, ensure_ascii=False) + "\n"

    if args.output:
        with open(args.output, "w", encoding="utf-8") as f:
            f.write(output)
    else:
        sys.stdout.write(output)


if __name__ == "__main__":
    main()
