import json
from pathlib import Path
from typing import Any, Dict, List, Tuple


def _load_profiles(project_root: Path) -> Dict[str, Any]:
    path = project_root / "config/webhook_profiles.json"
    return json.loads(path.read_text(encoding="utf-8"))


def _get_from_path(body: Dict[str, Any], key_path: str, headers: Dict[str, str]) -> Any:
    if key_path.startswith("header:"):
        return headers.get(key_path.replace("header:", ""), "")
    node: Any = body
    for part in key_path.split("."):
        if isinstance(node, dict) and part in node:
            node = node[part]
        else:
            return None
    return node


def _pick_first(body: Dict[str, Any], headers: Dict[str, str], paths: List[str]) -> Any:
    for p in paths:
        value = _get_from_path(body, p, headers)
        if value is None:
            continue
        if isinstance(value, str) and value.strip() == "":
            continue
        return value
    return None


def normalize_webhook(
    project_root: Path,
    channel: str,
    body: Dict[str, Any],
    headers: Dict[str, str],
) -> Tuple[bool, Dict[str, Any]]:
    profiles = _load_profiles(project_root)
    profile = profiles.get(channel)
    if not isinstance(profile, dict):
        return False, {"reason": "WEBHOOK_PROFILE_NOT_FOUND"}
    field_paths = profile.get("field_paths", {})
    tenant_id = _pick_first(body, headers, field_paths.get("tenant_id", []))
    text = _pick_first(body, headers, field_paths.get("text", []))
    approved = _pick_first(body, headers, field_paths.get("approved", []))
    if isinstance(text, str):
        try:
            text_json = json.loads(text)
            if isinstance(text_json, dict) and "text" in text_json:
                text = text_json.get("text")
        except Exception:
            pass
    if not text:
        return False, {"reason": "WEBHOOK_TEXT_MISSING"}
    result = {
        "role": profile.get("default_role", "admin"),
        "channel": profile.get("default_channel", channel),
        "tenant_id": str(tenant_id or "").strip(),
        "text": str(text).strip(),
        "approved": bool(approved) if approved is not None else True,
    }
    return True, result
