from __future__ import annotations

import json
import os
from pathlib import Path

import typer


def init_provider(
    out_dir: str,
    capability: str,
    provider_id: str,
    name: str,
    description: str,
    policy: list[str] | None,
) -> None:
    """Scaffold a minimal MRP provider wrapper (FastAPI).

    This creates a small project you can deploy anywhere. It implements:
    - GET /.well-known/mrp.json
    - GET /mrp/manifest
    - POST /mrp/discover
    - POST /mrp/execute

    Then you can self-register via: mrpd publish --manifest-url https://YOUR_DOMAIN/mrp/manifest
    """

    out = Path(out_dir).resolve()
    out.mkdir(parents=True, exist_ok=True)

    # Basic manifest (single capability)
    manifest = {
        "capability_id": f"capability:mrp/{capability}",
        "capability": capability,
        "version": "0.1",
        "tags": ["mrp"],
        "inputs": [{"type": "json"}],
        "outputs": [{"type": "json"}],
        "constraints": {"policy": policy or []},
        "proofs_required": [],
        "endpoints": {
            "discover": "/mrp/discover",
            "negotiate": "/mrp/negotiate",
            "execute": "/mrp/execute",
        },
    }

    (out / "mrp").mkdir(exist_ok=True)
    (out / "mrp" / "manifest.json").write_text(json.dumps(manifest, indent=2), encoding="utf-8")

    # A tiny FastAPI wrapper.
    app_py = f'''from __future__ import annotations

import json
from pathlib import Path

from fastapi import FastAPI

# Minimal MRP provider scaffold
# - Serve /.well-known/mrp.json + /mrp/manifest
# - Implement /mrp/discover + /mrp/execute

APP_DIR = Path(__file__).resolve().parent
MANIFEST_PATH = APP_DIR / "mrp" / "manifest.json"

app = FastAPI(title={name!r})


def _manifest() -> dict:
    return json.loads(MANIFEST_PATH.read_text(encoding="utf-8"))


@app.get("/.well-known/mrp.json")
def well_known() -> dict:
    # For deployed services, set manifest_url to an absolute URL.
    return {{
        "mrp_version": "0.1",
        "id": {provider_id!r},
        "name": {name!r},
        "description": {description!r},
        "manifest_url": "/mrp/manifest",
        "capabilities": [{capability!r}],
    }}


@app.get("/mrp/manifest")
def mrp_manifest() -> dict:
    return _manifest()


@app.post("/mrp/discover")
def mrp_discover(envelope: dict) -> dict:
    # Minimal discover: always offer the single capability
    req_id = envelope.get("msg_id")
    sender = (envelope.get("sender") or {{}}).get("id")

    offer = {{
        "route_id": f"route:{provider_id}/{capability}@0.1",
        "capability": {capability!r},
        "constraints": _manifest().get("constraints", {{}}),
        "cost": {{"unit": "usd", "estimate": 0}},
        "latency_ms": 0,
        "proofs": [],
    }}

    return {{
        "mrp_version": "0.1",
        "msg_id": str(__import__("uuid").uuid4()),
        "msg_type": "OFFER",
        "timestamp": __import__("datetime").datetime.utcnow().isoformat() + "Z",
        "sender": {{"id": {provider_id!r}}},
        "receiver": {{"id": sender}} if sender else None,
        "in_reply_to": req_id,
        "payload": {{"offers": [offer]}},
    }}


@app.post("/mrp/execute")
def mrp_execute(envelope: dict) -> dict:
    # TODO: implement your actual business logic here.
    req_id = envelope.get("msg_id")
    sender = (envelope.get("sender") or {{}}).get("id")

    payload = envelope.get("payload") or {{}}
    inputs = payload.get("inputs") or []

    # Convention: one json input with arbitrary value
    inp = next((i for i in inputs if isinstance(i, dict) and i.get("type") == "json"), None)
    value = inp.get("value") if isinstance(inp, dict) else None

    output = {{"ok": True, "echo": value}}

    return {{
        "mrp_version": "0.1",
        "msg_id": str(__import__("uuid").uuid4()),
        "msg_type": "EVIDENCE",
        "timestamp": __import__("datetime").datetime.utcnow().isoformat() + "Z",
        "sender": {{"id": {provider_id!r}}},
        "receiver": {{"id": sender}} if sender else None,
        "in_reply_to": req_id,
        "payload": {{
            "route_id": payload.get("route_id"),
            "outputs": [{{"type": "json", "value": output}}],
            "provenance": {{"citations": [], "timestamp": __import__("datetime").datetime.utcnow().isoformat() + "Z"}},
            "usage": {{"tokens_in_est": 0, "tokens_out_est": 0}},
            "job_id": (payload.get("job") or {{}}).get("id"),
        }},
    }}
'''

    (out / "app.py").write_text(app_py, encoding="utf-8")

    (out / "README.md").write_text(
        (
            f"# {name}\n\n"
            "This folder was generated by `mrpd init-provider`.\n\n"
            "## Run locally\n\n"
            "```bash\n"
            "python -m venv .venv\n"
            "# Windows: .\\.venv\\Scripts\\Activate.ps1\n"
            "pip install fastapi uvicorn httpx\n"
            "uvicorn app:app --host 127.0.0.1 --port 8787 --reload\n"
            "```\n\n"
            "## Self-register (HTTP-01)\n\n"
            "After deploying to a public HTTPS domain, run:\n\n"
            "```bash\n"
            "mrpd publish --manifest-url https://YOUR_DOMAIN/mrp/manifest\n"
            "```\n"
        ),
        encoding="utf-8",
    )

    typer.echo(f"Scaffolded provider in: {out}")
    typer.echo("Next: edit app.py to call your real app logic.")
    typer.echo("Then deploy, and run: mrpd publish --manifest-url https://YOUR_DOMAIN/mrp/manifest")
