"""
Irizpro Publish API v1 — receiver for Python (Flask).
Guide: https://<platform>/docs/publish-api

    pip install flask
    IRIZPRO_SITE_ID=site_... IRIZPRO_SIGNING_SECRET=irzsk_... flask --app receiver run

Endpoint: POST /irizpro-publish. For Django/FastAPI reuse handle(), passing the
RAW request body (the signature covers the exact bytes).
Implement save_post() at the bottom, then click "Send test" in Irizpro.
"""

import hashlib
import hmac
import json
import os
import time

from flask import Flask, jsonify, request

SITE_ID = os.environ.get("IRIZPRO_SITE_ID", "")
SIGNING_SECRET = os.environ.get("IRIZPRO_SIGNING_SECRET", "")

app = Flask(__name__)


def handle(headers, raw: bytes):
    if not SITE_ID or not SIGNING_SECRET:
        return 500, {"ok": False, "error": "Receiver is not configured"}

    # 1. Verify the signature on the raw body.
    ts = headers.get("X-Irizpro-Timestamp", "")
    sig = headers.get("X-Irizpro-Signature", "")
    if not ts.isdigit() or abs(time.time() - int(ts)) > 300:
        return 401, {"ok": False, "error": "Stale or missing timestamp"}
    expected = "sha256=" + hmac.new(SIGNING_SECRET.encode(), ts.encode() + b"." + raw, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, sig):
        return 401, {"ok": False, "error": "Invalid signature"}

    # 2. Parse and validate.
    try:
        p = json.loads(raw)
    except ValueError:
        return 400, {"ok": False, "error": "Body must be JSON"}
    if p.get("spec") != "irizpro.publish.v1":
        return 400, {"ok": False, "error": "Unsupported spec"}
    if p.get("site_id") != SITE_ID:
        return 401, {"ok": False, "error": "Wrong site_id"}
    post = p.get("post") or {}
    for f in ("external_id", "slug", "title", "content_html"):
        if not str(post.get(f) or "").strip():
            return 422, {"ok": False, "error": f"post.{f} is required"}

    # 3. Test deliveries: validate only, NEVER save.
    if p.get("event") == "post.test" or p.get("test"):
        return 200, {"ok": True, "test": True, "action": "validated"}
    if p.get("event") != "post.publish":
        return 400, {"ok": False, "error": "Unknown event"}

    # 4. Save (create, or update when external_id already exists).
    try:
        r = save_post(post)
    except Exception as e:  # noqa: BLE001
        return 500, {"ok": False, "error": f"Saving failed: {e}"}
    return 200, {"ok": True, "url": r["url"], "id": r.get("id"), "action": r.get("action", "created")}


def save_post(post: dict) -> dict:
    """Store the post your way; update when post['external_id'] already exists.
    Return {"url": <public URL>, "id": <your id>, "action": "created" | "updated"}."""
    raise NotImplementedError("save_post() is not implemented yet")


@app.post("/irizpro-publish")
def irizpro_publish():
    status, body = handle(request.headers, request.get_data())
    return jsonify(body), status
