"""line_bot.py — Flask webhook that lets a LINE user chat with the Hermes agent.

LINE sends a webhook POST whenever someone messages your Official Account.
This server verifies the signature, runs the message through the agent
from agent_pro.py, and replies with the agent's answer.

You need:
    1. A LINE Official Account + Messaging API channel
       https://developers.line.biz/console/
    2. Channel access token + channel secret (set in environment)
    3. A public HTTPS URL — easiest in dev: ngrok (`brew install ngrok`)

Setup:
    export LINE_CHANNEL_ACCESS_TOKEN="..."
    export LINE_CHANNEL_SECRET="..."

Run:
    python line_bot.py                 # listens on :8000
    ngrok http 8000                    # in another terminal — copy https URL
    # Paste <https-url>/webhook into the LINE console's Webhook URL.

Now LINE messages flow:
    LINE app → LINE servers → ngrok → :8000/webhook → Hermes agent → reply
"""
import base64
import hashlib
import hmac
import os

import requests
from flask import Flask, abort, request

from agent_pro import build_agent

app = Flask(__name__)
agent = build_agent()

LINE_TOKEN = os.environ["LINE_CHANNEL_ACCESS_TOKEN"]
LINE_SECRET = os.environ["LINE_CHANNEL_SECRET"].encode()


def _signature_ok(body: bytes, header: str) -> bool:
    """Verify the LINE webhook signature so attackers can't fake messages."""
    mac = hmac.new(LINE_SECRET, body, hashlib.sha256).digest()
    expected = base64.b64encode(mac).decode()
    return hmac.compare_digest(expected, header or "")


def reply(reply_token: str, text: str) -> None:
    """Send one text reply back to the user."""
    requests.post(
        "https://api.line.me/v2/bot/message/reply",
        headers={
            "Authorization": f"Bearer {LINE_TOKEN}",
            "Content-Type": "application/json",
        },
        json={
            "replyToken": reply_token,
            "messages": [{"type": "text", "text": text[:4900]}],
        },
        timeout=10,
    )


@app.post("/webhook")
def webhook():
    body = request.get_data()
    if not _signature_ok(body, request.headers.get("X-Line-Signature", "")):
        abort(401)
    for event in request.json.get("events", []):
        if event.get("type") == "message" and event["message"]["type"] == "text":
            user_text = event["message"]["text"]
            print(f"LINE user > {user_text}")
            response = str(agent.chat(user_text))
            print(f"agent > {response}")
            reply(event["replyToken"], response)
    return "ok"


@app.get("/")
def health():
    return "LINE bot alive"


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)
