"""Отправка в системные webhooks (s2s): подпись app/signature.py, docs/05.

Секрет цели — per-target: channel_targets.config = {"endpoint": …, "token_ref":
"navi-rei"}; значение секрета — в окружении (S2S_SECRET_NAVI_REI, .env /
gnexus-creds), в БД только ссылка. Ротация секрета цели не трогает правила.
"""

import json
import os
import time

import httpx

from app.models import ChannelTarget, Event
from app.signature import make_signature

#: Референс-получателю достаточно этих трёх; остальное — настройка цели.
S2S_TIMEOUT = httpx.Timeout(10.0)


def secret_env_name(token_ref: str) -> str:
    """token_ref «navi-rei» → переменная окружения S2S_SECRET_NAVI_REI."""
    cleaned = token_ref.upper().replace("-", "_").replace(".", "_")
    return f"S2S_SECRET_{cleaned}"


def resolve_secret(token_ref: str) -> str | None:
    return os.environ.get(secret_env_name(token_ref)) or None


def send_s2s(target: ChannelTarget, event: Event, source_name: str) -> tuple[bool, str | None]:
    """POST конверта события в endpoint цели, подписанный по схеме gnexus-auth.

    Тело — конверт без изменений + event_id (см. docs/05):
    описание источника в него не входит. Успех — любой 2xx; прочее —
    провал попытки (воркер поставит ретрай).
    """
    cfg = target.config or {}
    endpoint = cfg.get("endpoint")
    token_ref = cfg.get("token_ref")
    if not endpoint:
        return False, "s2s: в config цели нет endpoint"
    secret = resolve_secret(token_ref) if token_ref else None
    if not secret:
        return False, (
            f"s2s: секрет цели не задан в окружении "
            f"({secret_env_name(token_ref) if token_ref else 'нет token_ref в config'})"
        )

    envelope = {
        "event_id": str(event.id),
        "source": source_name,
        "subject": event.subject,
        "action": event.action,
        "priority": event.priority,
        "payload": dict(event.payload or {}),
    }
    body = json.dumps(envelope, ensure_ascii=False, separators=(",", ":")).encode()
    headers = {
        "Content-Type": "application/json",
        "X-Gnexus-Event-Id": str(event.id),
        "X-Gnexus-Event-Type": f"{source_name}.{event.subject}.{event.action}",
        "X-Gnexus-Event-Timestamp": str(int(time.time())),
        "X-Gnexus-Signature": make_signature(body, secret),
        "X-Synapse-Source": source_name,
        "User-Agent": "Synapse/0.1 (gnexus notification hub)",
    }
    try:
        response = httpx.post(
            endpoint,
            content=body,
            headers=headers,
            timeout=S2S_TIMEOUT,
            verify=cfg.get("verify_tls", True),
            follow_redirects=False,
        )
    except httpx.HTTPError as err:
        return False, f"s2s: сеть: {err}"

    if 200 <= response.status_code < 300:
        return True, None
    return False, f"s2s: HTTP {response.status_code} · {response.text[:200]}"