#!/usr/bin/env python3
"""
WA-AKG Webhook Receiver — PX3 Lab / Monique

Fluxo:
  WA-AKG (wa-akg-app)  --POST-->  este receiver  --JSONL-->  /opt/mia/logs/wa_akg_monique.jsonl
                                      |
                                      +---> (TODO futuro) espelha pro Linkia PX3 como nota no contato

Validação:
  - Compara header X-Webhook-Secret com WA_AKG_WEBHOOK_SECRET
  - Rejeita 401 se não bater

Endpoints:
  GET  /health          -> {"status":"ok"}
  POST /webhook/monique -> armazena evento (precisa secret)
  POST /webhook/<slug>  -> armazena evento genérico (um JSONL por slug) — pra multi-cliente futuro

Loga TUDO que chega. Nada de drop silencioso. Debug > perfeição nesse momento.
"""
from __future__ import annotations

import json
import logging
import os
import pathlib
import time
from datetime import datetime, timezone

from flask import Flask, Response, abort, jsonify, request

LOGS_DIR = pathlib.Path(os.environ.get("WA_AKG_LOGS_DIR", "/opt/mia/logs"))
LOGS_DIR.mkdir(parents=True, exist_ok=True)

SECRET = os.environ.get("WA_AKG_WEBHOOK_SECRET", "").strip()
if not SECRET:
    # Falha barulhenta: não quero rodar sem secret por engano.
    raise SystemExit(
        "WA_AKG_WEBHOOK_SECRET nao definido. "
        "Carregue /opt/mia/config/wa_akg.env antes de subir o receiver."
    )

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
)
log = logging.getLogger("wa_akg_receiver")

app = Flask(__name__)


def _jsonl_path(slug: str) -> pathlib.Path:
    safe = "".join(c for c in slug if c.isalnum() or c in ("-", "_")).lower() or "default"
    return LOGS_DIR / f"wa_akg_{safe}.jsonl"


def _store(slug: str, payload: dict, meta: dict) -> None:
    row = {
        "received_at": datetime.now(timezone.utc).isoformat(),
        "slug": slug,
        "meta": meta,
        "payload": payload,
    }
    with _jsonl_path(slug).open("a", encoding="utf-8") as f:
        f.write(json.dumps(row, ensure_ascii=False) + "\n")


def _check_secret() -> None:
    # WA-AKG costuma mandar o secret no header `x-webhook-secret` ou numa query `?secret=`
    header = (
        request.headers.get("X-Webhook-Secret")
        or request.headers.get("X-Secret")
        or request.args.get("secret")
        or ""
    ).strip()
    if header != SECRET:
        log.warning(
            "secret invalido ou ausente — remote=%s header_len=%d",
            request.remote_addr,
            len(header),
        )
        abort(401)


@app.route("/health", methods=["GET"])
def health() -> Response:
    return jsonify({"status": "ok", "ts": int(time.time())})


@app.route("/webhook/<slug>", methods=["POST"])
def webhook(slug: str):
    _check_secret()
    try:
        payload = request.get_json(force=True, silent=False) or {}
    except Exception as e:  # noqa: BLE001
        log.exception("payload invalido")
        return jsonify({"ok": False, "error": f"invalid json: {e}"}), 400

    meta = {
        "remote_addr": request.remote_addr,
        "user_agent": request.headers.get("User-Agent"),
        "event_header": request.headers.get("X-Event"),
    }
    _store(slug, payload, meta)
    event = payload.get("event") or payload.get("type") or "unknown"
    session = payload.get("sessionId") or payload.get("session") or "-"
    log.info("stored slug=%s event=%s session=%s", slug, event, session)
    return jsonify({"ok": True})


@app.route("/", methods=["GET"])
def index():
    return jsonify(
        {
            "service": "wa-akg-receiver",
            "endpoints": {
                "health": "GET /health",
                "monique": "POST /webhook/monique?secret=XXX",
                "generic": "POST /webhook/<slug>?secret=XXX",
            },
            "logs_dir": str(LOGS_DIR),
        }
    )


if __name__ == "__main__":
    port = int(os.environ.get("WA_AKG_RECEIVER_PORT", "8971"))
    # Default bind: 0.0.0.0 pra o container Docker do WA-AKG alcançar o host
    # pelo gateway da bridge (ex.: 172.19.0.1). Pra restringir a localhost basta
    # setar WA_AKG_RECEIVER_HOST=127.0.0.1.
    host = os.environ.get("WA_AKG_RECEIVER_HOST", "0.0.0.0")
    app.run(host=host, port=port, debug=False)
