"""
Portarus Starter — webhook handler for LangChain agents
=======================================================

LangChain is a framework, not a hosted webhook platform, so there is no
"production URL" to copy — YOU expose this endpoint and paste its public
HTTPS URL into the Portarus Destination URL field.

What this does
--------------
Receives the Portarus `_portarus` envelope, verifies the shared secret,
acks fast with 200, and hands the clean message off to your agent.

Run
---
    pip install fastapi uvicorn
    export PORTARUS_SECRET="<the secret shown in Portarus>"
    uvicorn portarus_handler:app --host 0.0.0.0 --port 8000

Then expose it over HTTPS (your host, a tunnel, a reverse proxy) and paste
that URL into Portarus. Portarus authenticates every delivery with an
`Authorization: Bearer <secret>` header — paste that same secret into
PORTARUS_SECRET below.
"""

import os
from fastapi import FastAPI, Request, Header, HTTPException

app = FastAPI()

PORTARUS_SECRET = os.environ.get("PORTARUS_SECRET", "")


# --- The _portarus envelope -------------------------------------------------
# Final message text → body["_portarus"]["message"] (already unified)
# Did Portarus run    → body["_portarus"]["status"]["processed"]
# Security verdict     → body["_portarus"]["security"]["result"]


@app.post("/portarus")
async def portarus_webhook(
    request: Request,
    authorization: str | None = Header(default=None),
):
    # 1) Verify the shared secret — Portarus sends `Authorization: Bearer <secret>`
    expected = f"Bearer {PORTARUS_SECRET}"
    if not PORTARUS_SECRET or authorization != expected:
        raise HTTPException(status_code=401, detail="Unauthorized")

    body = await request.json()
    env = body.get("_portarus", {})

    # 2) Hand the clean, unified message off to your agent.
    #    If you already have an agent, nothing breaks — Portarus just hands it
    #    a cleaner prompt. If you're new, build from here.
    prompt = env.get("message", "")
    reply = run_agent(prompt=prompt, env=env)

    # 3) Ack 200 fast, so Portarus doesn't time out → retries → duplicates.
    return {"received": True, "trace_id": (env.get("meta") or {}).get("trace_id")}


def run_agent(prompt: str, env: dict) -> str:
    """→ Your current process. Wire your LangChain chain/agent here.

    from langchain_openai import ChatOpenAI
    from langchain_core.messages import HumanMessage
    llm = ChatOpenAI(model="gpt-4o-mini")
    return llm.invoke([HumanMessage(content=prompt)]).content
    """
    return f"(replace run_agent) received: {prompt!r}"
