import logging
import re
from typing import Any

import requests

from apps.masterdata.platform_setting import PlatformSetting

logger = logging.getLogger(__name__)


def _get_meta_cloud_config() -> dict[str, str]:
    return {
        "base_url": (PlatformSetting.get_value("whatsapp_meta_base_url", "https://graph.facebook.com") or "https://graph.facebook.com").strip().rstrip("/"),
        "api_version": (PlatformSetting.get_value("whatsapp_meta_api_version", "v20.0") or "v20.0").strip(),
        "phone_number_id": PlatformSetting.get_value("whatsapp_meta_phone_number_id", "").strip(),
        "access_token": PlatformSetting.get_value("whatsapp_meta_access_token", "").strip(),
        "default_country_code": (PlatformSetting.get_value("whatsapp_default_country_code", "+91") or "+91").strip(),
    }


def _normalize_recipient(raw_number: str, default_country_code: str) -> str:
    cleaned = re.sub(r"[^0-9+]", "", str(raw_number or "").strip())
    if not cleaned:
        return ""

    if cleaned.startswith("+"):
        return f"+{re.sub(r'[^0-9]', '', cleaned)}"

    digits = re.sub(r"[^0-9]", "", cleaned)
    cc_digits = re.sub(r"[^0-9]", "", default_country_code or "")
    if cc_digits and not digits.startswith(cc_digits):
        digits = f"{cc_digits}{digits}"
    return f"+{digits}"


def _build_meta_payload(recipient: str, message_type: str, text: str, media_url: str) -> dict[str, Any]:
    payload: dict[str, Any] = {
        "messaging_product": "whatsapp",
        "to": recipient,
        "type": message_type,
    }

    if message_type == "text":
        payload["text"] = {
            "preview_url": False,
            "body": text,
        }
        return payload

    media_obj: dict[str, Any] = {"link": media_url}

    if message_type in {"image", "video", "document"} and text:
        media_obj["caption"] = text
    if message_type == "document":
        media_obj["filename"] = "attachment"

    payload[message_type] = media_obj
    return payload


def send_whatsapp_message(*, recipient: str, message_type: str, text: str = "", media_url: str = "") -> dict[str, Any]:
    enabled = PlatformSetting.get_bool("whatsapp_enabled", False)
    if not enabled:
        raise RuntimeError("WhatsApp service is disabled. Enable it from admin settings.")

    provider = (PlatformSetting.get_value("whatsapp_active_provider", "meta_cloud") or "meta_cloud").strip()
    if provider != "meta_cloud":
        raise RuntimeError("Unsupported WhatsApp provider. Set provider to meta_cloud.")

    config = _get_meta_cloud_config()
    if not config["phone_number_id"] or not config["access_token"]:
        raise RuntimeError("Meta WhatsApp credentials are incomplete. Configure phone number ID and access token.")

    normalized = _normalize_recipient(recipient, config["default_country_code"])
    if not normalized:
        raise RuntimeError("Invalid recipient mobile number.")

    outbound_type = message_type if message_type in {"text", "image", "video", "audio", "document"} else "text"
    if outbound_type == "text" and not text.strip():
        raise RuntimeError("Text message cannot be empty.")
    if outbound_type in {"image", "video", "audio", "document"} and not media_url.strip():
        raise RuntimeError(f"media_url is required for {outbound_type} message type.")

    payload = _build_meta_payload(normalized, outbound_type, text.strip(), media_url.strip())
    endpoint = f"{config['base_url']}/{config['api_version']}/{config['phone_number_id']}/messages"
    headers = {
        "Authorization": f"Bearer {config['access_token']}",
        "Content-Type": "application/json",
    }

    try:
        response = requests.post(endpoint, json=payload, headers=headers, timeout=15)
        parsed = {}
        try:
            parsed = response.json() if response.content else {}
        except Exception:
            parsed = {"raw": response.text}

        if response.status_code >= 400:
            logger.error("WhatsApp send failed. recipient=%s status=%s body=%s", normalized, response.status_code, parsed)
            return {
                "ok": False,
                "provider": "meta_cloud",
                "recipient": normalized,
                "status_code": response.status_code,
                "error": parsed,
            }

        message_id = None
        messages = parsed.get("messages") if isinstance(parsed, dict) else None
        if isinstance(messages, list) and messages:
            message_id = messages[0].get("id")

        return {
            "ok": True,
            "provider": "meta_cloud",
            "recipient": normalized,
            "status_code": response.status_code,
            "message_id": message_id,
            "response": parsed,
        }
    except Exception as exc:
        logger.exception("WhatsApp send exception for recipient=%s", normalized)
        return {
            "ok": False,
            "provider": "meta_cloud",
            "recipient": normalized,
            "error": str(exc),
        }
