"""Trigger-Workflow: findet unbearbeitete Belege im aktuellen Account.

Filter-Kette:

1. ``isArchived == false`` (nur unarchivierte Belege)
2. Kein blockierender Tag (``agent-done``, ``agent-skip``, ``agent-review``,
   ``agent-compliance-hold``)
3. Pro Beleg wird ``missing_fields`` über die Pflichtfeld-Liste berechnet.

Jeder Treffer bekommt ein ``mode``-Feld:

- ``extract`` — Pflichtfeld fehlt
- ``verify``  — alle Pflichtfelder gesetzt

Mit ``--single UID`` wird ein einzelner Beleg über
``fetch_one_document_meta_via_list`` gezogen (schont das Per-UID-Daily-Limit
von getOneDocument).
"""
from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path
from typing import Optional


_SKILL_DIR = Path(__file__).resolve().parent.parent
_SKILLS_ROOT = _SKILL_DIR.parent
if str(_SKILLS_ROOT) not in sys.path:
    sys.path.insert(0, str(_SKILLS_ROOT))
if str(_SKILL_DIR) not in sys.path:
    sys.path.insert(0, str(_SKILL_DIR))


_BLOCK_TAGS = {"agent-skip", "agent-done", "agent-review", "agent-compliance-hold"}

# Mapping: Pflichtfeld-Name (gmi-accountant-Konvention) → GMI-API-Feldname
_FIELD_TO_DOC = {
    "supplier": "companyName",
    "documentNumber": "documentNumber",
    "documentDate": "documentDate",
    "grossAmount": "grossAmount",
    "currency": "currency",
    "documentType": "documentType",
}


def _load_pflichtfelder() -> list:
    """Lädt die Pflichtfeld-Liste aus dem skill-lokalen pflichtfelder.json.

    Das File wird vom Setup-Agent aus ``templates/.skills/gmi-accountant/
    pflichtfelder.json`` kopiert oder vom Eval-Runner als Fixture
    angelegt. Fehlt es, wird das MVP-Default-Set zurückgegeben.
    """
    pf_file = _SKILL_DIR / "pflichtfelder.json"
    if pf_file.is_file():
        data = json.loads(pf_file.read_text(encoding="utf-8"))
        return data.get("pflichtfelder", []) or []
    return [
        "supplier", "documentNumber", "documentDate",
        "grossAmount", "currency", "documentType",
    ]


def missing_pflichtfelder(doc: dict) -> list:
    """Liefert die fehlenden Pflichtfeld-Namen für einen Beleg."""
    pf = _load_pflichtfelder()
    missing = []
    for field in pf:
        doc_key = _FIELD_TO_DOC.get(field, field)
        val = doc.get(doc_key)
        if val is None or val == "" or val == 0 or val == 0.0:
            missing.append(field)
    return missing


def passes_ampel(doc: dict) -> bool:
    """True wenn der Beleg durch den Agent laufen soll (Tag-Ampel-Filter)."""
    if doc.get("isArchived"):
        return False
    tags = set(doc.get("tags") or [])
    if tags & _BLOCK_TAGS:
        return False
    return True


def workflow_mode(doc: dict, *, enable_verify_mode: bool = True) -> str:
    """'extract' bei fehlenden Pflichtfeldern, sonst 'verify'."""
    if not enable_verify_mode:
        return "extract"
    return "extract" if missing_pflichtfelder(doc) else "verify"


def _build_record(doc: dict, *, enable_verify_mode: bool) -> dict:
    return {
        "uid": doc.get("documentUid"),
        "supplier": doc.get("companyName", ""),
        "grossAmount": doc.get("grossAmount", 0.0),
        "missing_fields": missing_pflichtfelder(doc),
        "mode": workflow_mode(doc, enable_verify_mode=enable_verify_mode),
    }


def run(
    limit: Optional[int],
    single: Optional[int],
    enable_verify_mode: bool = True,
) -> int:
    try:
        from gmi_bridge import (  # noqa: WPS433
            build_client,
            fetch_document_list,
            fetch_one_document_meta_via_list,
        )
    except (FileNotFoundError, ImportError) as e:
        print(json.dumps({"error": f"depends_on-Vertrag verletzt: {e}"}, ensure_ascii=False))
        return 3

    try:
        client = build_client()
    except Exception:
        print(json.dumps({"error": "Bridge konnte nicht aufgebaut werden."}, ensure_ascii=False))
        return 2

    if single is not None:
        raw = fetch_one_document_meta_via_list(client, single)
        if raw is None:
            print(json.dumps({
                "error": f"UID {single} wurde in getDocumentList nicht gefunden.",
            }, ensure_ascii=False))
            return 4
        meta = raw.get("meta_data", raw)
        record = _build_record(meta, enable_verify_mode=enable_verify_mode)
        record["uid"] = single
        print(json.dumps([record], ensure_ascii=False, indent=2))
        return 0

    result: list = []
    count = 0
    for doc in fetch_document_list(client, archivedFilter=0):
        if not passes_ampel(doc):
            continue
        result.append(_build_record(doc, enable_verify_mode=enable_verify_mode))
        count += 1
        if limit and count >= limit:
            break

    print(json.dumps(result, ensure_ascii=False, indent=2))
    return 0


def main() -> int:
    p = argparse.ArgumentParser(description="gmi-accountant Trigger")
    p.add_argument("--limit", type=int, default=None,
                   help="Maximale Anzahl Belege im Output.")
    p.add_argument("--single", type=int, default=None,
                   help="Nur diese UID prüfen.")
    p.add_argument("--no-verify-mode", action="store_true",
                   help="enable_verify_mode=false. Alle Belege gehen extract-Pfad.")
    args = p.parse_args()
    return run(args.limit, args.single, enable_verify_mode=not args.no_verify_mode)


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