"""Workflow: Dokumente (PDFs) und optional Anhänge lokal ablegen.

Aufruf:
  python download_documents.py --uids uid1,uid2 --target "07 Anhänge/GMI/2026-04/"
  python download_documents.py --uids uid1 --target ./out --with-attachments
"""
from __future__ import annotations

import argparse
import json
import re
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent))

from gmi_client import GmiClient, GmiHttpError  # noqa: E402


def slugify(s: str) -> str:
    s = re.sub(r"[^A-Za-z0-9._-]+", "_", s or "unbekannt")
    return s.strip("_")[:60]


def unique_path(base: Path) -> Path:
    if not base.exists():
        return base
    stem, suffix = base.stem, base.suffix
    i = 2
    while True:
        candidate = base.with_name(f"{stem}_{i}{suffix}")
        if not candidate.exists():
            return candidate
        i += 1


def download_one(client: GmiClient, uid: str, target_dir: Path, with_attachments: bool) -> dict:
    response = client.call("getOneDocument", documentUid=uid)
    if not isinstance(response, dict):
        return {"uid": uid, "error": "no_metadata"}

    # getOneDocument liefert {meta_data: {...}, fileContent: <base64>}
    meta = response.get("meta_data", {}) if isinstance(response.get("meta_data"), dict) else response

    date = meta.get("documentDate") or "nodate"
    supplier = slugify(meta.get("companyName", ""))
    number = slugify(meta.get("documentNumber", ""))
    filename = f"{date}_{supplier}_{number}.pdf"
    pdf_path = unique_path(target_dir / filename)

    pdf_bytes = client.call("downloadDocument", documentUid=uid)
    if not isinstance(pdf_bytes, (bytes, bytearray)):
        return {"uid": uid, "error": "no_file_bytes"}

    pdf_path.parent.mkdir(parents=True, exist_ok=True)
    pdf_path.write_bytes(pdf_bytes)
    result = {"uid": uid, "pdf": str(pdf_path), "bytes": len(pdf_bytes), "attachments": []}

    if with_attachments:
        try:
            atts = client.call("getAttachmentList", documentUid=uid)
            att_items = atts.get("attachments", []) if isinstance(atts, dict) else []
        except GmiHttpError:
            att_items = []
        att_dir = pdf_path.parent / pdf_path.stem
        for att in att_items:
            att_uid = att.get("attachmentUid")
            if not att_uid:
                continue
            try:
                att_bytes = client.call_path(
                    "GET",
                    f"/documents/{uid}/attachments/{att_uid}",
                )
            except GmiHttpError:
                continue
            if not isinstance(att_bytes, (bytes, bytearray)):
                continue
            att_dir.mkdir(parents=True, exist_ok=True)
            att_name = slugify(att.get("filename", att_uid))
            att_path = unique_path(att_dir / att_name)
            att_path.write_bytes(att_bytes)
            result["attachments"].append({"path": str(att_path), "bytes": len(att_bytes)})

    return result


def main() -> int:
    p = argparse.ArgumentParser()
    p.add_argument("--uids", required=True, help="Komma-separierte documentUids")
    p.add_argument("--target", required=True, help="Zielordner")
    p.add_argument("--with-attachments", action="store_true")
    args = p.parse_args()

    target = Path(args.target)
    uids = [u.strip() for u in args.uids.split(",") if u.strip()]

    try:
        client = GmiClient()
    except Exception as e:
        print(json.dumps({"error": "config", "detail": str(e)}))
        return 1

    results = []
    for uid in uids:
        try:
            results.append(download_one(client, uid, target, args.with_attachments))
        except GmiHttpError as e:
            results.append({"uid": uid, "error": "http", "status": e.status})

    print(json.dumps({"results": results, "count": len(results)}, indent=2, ensure_ascii=False))
    return 0


if __name__ == "__main__":
    sys.exit(main())
