"""Quickstart — nined-memory SDK usage examples.

Install:
    pip install --index-url https://test.pypi.org/simple/ nined-memory

Requires a running Memory Runtime API server (default: http://localhost:3000).
"""

from nined.memory import (
    MemoryClient,
    MemoryClientV2,
    AuthorizationError,
    MemoryAPIError,
    NotFoundError,
    PolicyDeniedError,
    RateLimitError,
    __version__,
)


def demo_v1():
    """Demonstrate MemoryClient (v1 API)."""
    print("=" * 60)
    print(f"nined-memory v{__version__} — v1 API (MemoryClient)")
    print("=" * 60)

    client = MemoryClient(
        base_url="http://localhost:3000",
        api_key="your-api-key",
    )

    # Health check (no auth required)
    print("\n--- Health ---")
    health = client.health()
    print(f"Status: {health}")

    # Ingest a document
    print("\n--- Ingest ---")
    result = client.ingest(
        workspace_id="demo-ws",
        actor_id="demo-agent",
        artifact_type="document",
        raw_payload={
            "title": "Deploy Runbook",
            "content": "If auth service fails, restart the pod. Check /health first.",
        },
    )
    print(f"Ingested: {result}")
    artifact_id = result.get("artifact_id", "unknown")

    # Check artifact indexing status
    print("\n--- Artifact Status ---")
    status = client.artifact_status(artifact_id)
    print(f"Indexed: {status}")

    # Retrieve a context pack
    print("\n--- Context Pack ---")
    pack = client.context_pack(
        query="What should I do if auth fails?",
        workspace_id="demo-ws",
        max_tokens=4096,
    )
    print(f"Context: {pack.get('context_text', '')[:200]}...")
    print(f"Confidence: {pack.get('confidence')}")
    print(f"Receipt ID: {pack.get('receipt_id')}")

    # Context pack with tuning parameters
    print("\n--- Context Pack (tuned) ---")
    tuned_pack = client.context_pack(
        query="deployment procedures",
        workspace_id="demo-ws",
        max_tokens=8192,
        mode="coverage",
        diversity_decay=0.5,
    )
    print(f"Tuned pack tokens: {tuned_pack.get('total_tokens')}")

    # Submit feedback
    print("\n--- Feedback ---")
    fb = client.feedback(
        workspace_id="demo-ws",
        actor_id="demo-agent",
        action="pin",
        artifact_id=artifact_id,
        reason="Critical runbook — always include",
    )
    print(f"Feedback: {fb}")

    # List receipts
    print("\n--- Receipts ---")
    receipts = client.list_receipts(workspace_id="demo-ws", limit=5)
    print(f"Receipt count: {receipts.get('total_count', 0)}")

    # Get a single receipt
    receipt_id = pack.get("receipt_id")
    if receipt_id:
        print(f"\n--- Get Receipt {receipt_id} ---")
        receipt = client.get_receipt(receipt_id)
        print(f"Receipt: {receipt}")

    # LLM-synthesized answer
    print("\n--- Ask (LLM synthesis) ---")
    answer = client.ask(
        query="What should I do if auth fails?",
        workspace_id="demo-ws",
    )
    print(f"Answer: {answer.get('answer', '')[:200]}")
    print(f"Confidence: {answer.get('confidence')}")

    # Registration & billing (multi-tenant mode)
    print("\n--- Register ---")
    reg = client.register("demo@example.com")
    print(f"Registration: {reg}")

    print("\n--- Billing ---")
    usage = client.billing_usage()
    print(f"Usage: {usage}")
    plan = client.billing_plan()
    print(f"Plan: {plan}")

    # Clean up
    print("\n--- Delete Workspace ---")
    deleted = client.delete_workspace("demo-ws")
    print(f"Deleted: {deleted}")


def demo_v2():
    """Demonstrate MemoryClientV2 (v2 API)."""
    print("\n" + "=" * 60)
    print(f"nined-memory v{__version__} — v2 API (MemoryClientV2)")
    print("=" * 60)

    client = MemoryClientV2(
        base_url="http://localhost:3000",
        api_key="your-api-key",
        workspace_id="demo-ws",
        actor_id="demo-agent",
    )

    # Health & readiness (no auth required)
    print("\n--- Health ---")
    print(f"Health: {client.health()}")
    print(f"Ready: {client.ready()}")

    # Batch ingest (synchronous)
    print("\n--- Batch Ingest (sync) ---")
    result = client.ingest([
        {
            "artifact_type": "document",
            "raw_payload": {
                "title": "Deploy Runbook",
                "content": "If auth service fails, restart the pod.",
            },
        },
        {
            "artifact_type": "note",
            "raw_payload": {
                "content": "Meeting notes: decided to migrate to K8s by Q2.",
            },
        },
    ])
    print(f"Ingested: {result}")

    # Batch ingest (async — background indexing)
    print("\n--- Batch Ingest (async) ---")
    async_result = client.ingest(
        [{"artifact_type": "document", "raw_payload": {"content": "Async doc..."}}],
        async_index=True,
    )
    print(f"Queued: {async_result}")

    # Track async job status
    jobs = async_result.get("queued_jobs", [])
    if jobs:
        job_id = jobs[0]["job_id"]
        print(f"\n--- Job Status ({job_id}) ---")
        job = client.job_status(job_id)
        print(f"Job state: {job.get('state')}")

    # Context pack with serving profiles
    print("\n--- Context Pack (balanced — default) ---")
    pack = client.context_pack("What should I do if auth fails?")
    print(f"Pack hash: {pack.get('pack_hash')}")
    for snippet in pack.get("snippets", []):
        print(f"  - {snippet.get('content', '')[:100]}...")

    print("\n--- Context Pack (high_recall) ---")
    pack_hr = client.context_pack(
        "deployment timeline",
        profile="high_recall",
        max_tokens=8192,
    )
    print(f"Snippets: {len(pack_hr.get('snippets', []))}")

    print("\n--- Context Pack (low_latency) ---")
    pack_ll = client.context_pack("auth fix", profile="low_latency")
    print(f"Profile used: {pack_ll.get('serving_profile')}")

    # Artifact status
    ingested = result.get("ingested", [])
    if ingested:
        aid = ingested[0].get("artifact_id", "unknown")
        print(f"\n--- Artifact Status ({aid}) ---")
        status = client.artifact_status(aid)
        print(f"Status: {status}")

    # Feedback
    print("\n--- Feedback ---")
    if ingested:
        fb = client.feedback("pin", artifact_id=ingested[0].get("artifact_id"))
        print(f"Feedback: {fb}")

    # Receipts
    print("\n--- Receipts ---")
    receipts = client.list_receipts(limit=5)
    print(f"Receipts: {receipts}")

    pack_hash = pack.get("pack_hash")
    if pack_hash:
        print(f"\n--- Get Receipt ({pack_hash}) ---")
        receipt = client.get_receipt(pack_hash)
        print(f"Receipt: {receipt}")

    # LLM-synthesized answer
    print("\n--- Ask ---")
    answer = client.ask("What should I do if auth fails?", profile="balanced")
    print(f"Answer: {answer.get('answer', '')[:200]}")

    # Clean up
    print("\n--- Delete Workspace ---")
    deleted = client.delete_workspace()
    print(f"Deleted: {deleted}")


def demo_error_handling():
    """Demonstrate error handling with the SDK."""
    print("\n" + "=" * 60)
    print("Error Handling Examples")
    print("=" * 60)

    client = MemoryClient(base_url="http://localhost:3000", api_key="bad-key")

    # 404 — Not Found
    print("\n--- NotFoundError ---")
    try:
        client.get_receipt("nonexistent-receipt-id")
    except NotFoundError as e:
        print(f"Caught NotFoundError: {e}")

    # 401/403 — Authorization
    print("\n--- AuthorizationError ---")
    try:
        client.context_pack(query="test", workspace_id="ws")
    except AuthorizationError as e:
        print(f"Caught AuthorizationError: {e}")

    # 403 — Policy denied
    print("\n--- PolicyDeniedError ---")
    try:
        client.context_pack(query="restricted query", workspace_id="ws")
    except PolicyDeniedError as e:
        print(f"Caught PolicyDeniedError: {e}")

    # 429 — Rate limit
    print("\n--- RateLimitError ---")
    try:
        client.ingest(workspace_id="ws", actor_id="a", artifact_type="document")
    except RateLimitError as e:
        print(f"Caught RateLimitError: {e}")

    # Catch-all for any API error
    print("\n--- MemoryAPIError (base class) ---")
    try:
        client.health()
    except MemoryAPIError as e:
        print(f"Caught MemoryAPIError: status={e.status_code}, detail={e.detail}")


if __name__ == "__main__":
    print("nined-memory SDK Quickstart")
    print(f"Version: {__version__}\n")

    try:
        demo_v1()
    except Exception as e:
        print(f"\n[v1 demo stopped: {type(e).__name__}: {e}]")
        print("(This is expected if the API server is not running)\n")

    try:
        demo_v2()
    except Exception as e:
        print(f"\n[v2 demo stopped: {type(e).__name__}: {e}]")
        print("(This is expected if the API server is not running)\n")

    try:
        demo_error_handling()
    except Exception as e:
        print(f"\n[Error handling demo stopped: {type(e).__name__}: {e}]")
        print("(This is expected if the API server is not running)\n")

    print("\nDone.")
