"""WhatsApp Business Cloud API client."""

from __future__ import annotations

import json
import logging
import urllib.error
import urllib.request
from dataclasses import dataclass

from app.core.config import Settings, get_settings
from app.utils.helpers import normalize_whatsapp_recipient

logger = logging.getLogger(__name__)


class WhatsAppCloudError(Exception):
    def __init__(self, message: str, *, status_code: int | None = None, response: dict | None = None):
        super().__init__(message)
        self.status_code = status_code
        self.response = response or {}


@dataclass
class WhatsAppSendResult:
    message_id: str
    recipient: str
    template_name: str


class WhatsAppCloudClient:
    def __init__(self, settings: Settings | None = None):
        self.settings = settings or get_settings()

    @property
    def enabled(self) -> bool:
        return self.settings.whatsapp_configured

    def send_template_message(
        self,
        mobile: str,
        *,
        template_name: str | None = None,
        language_code: str | None = None,
        body_parameters: list[str],
    ) -> WhatsAppSendResult:
        if not self.enabled:
            raise WhatsAppCloudError("WhatsApp Cloud API is not configured")

        template = template_name or self.settings.whatsapp_template_name
        language = language_code or self.settings.whatsapp_template_language
        recipient = normalize_whatsapp_recipient(mobile)

        payload = {
            "messaging_product": "whatsapp",
            "to": recipient,
            "type": "template",
            "template": {
                "name": template,
                "language": {"code": language},
                "components": [
                    {
                        "type": "body",
                        "parameters": [{"type": "text", "text": value} for value in body_parameters],
                    }
                ],
            },
        }

        url = (
            f"https://graph.facebook.com/{self.settings.whatsapp_api_version}/"
            f"{self.settings.whatsapp_phone_number_id}/messages"
        )
        request = urllib.request.Request(
            url,
            data=json.dumps(payload).encode("utf-8"),
            headers={
                "Authorization": f"Bearer {self.settings.whatsapp_api_token}",
                "Content-Type": "application/json",
            },
            method="POST",
        )

        try:
            with urllib.request.urlopen(request, timeout=30) as response:
                body = json.loads(response.read().decode("utf-8"))
        except urllib.error.HTTPError as exc:
            raw = exc.read().decode("utf-8", errors="replace")
            try:
                parsed = json.loads(raw)
            except json.JSONDecodeError:
                parsed = {"raw": raw}
            message = parsed.get("error", {}).get("message") if isinstance(parsed.get("error"), dict) else raw
            raise WhatsAppCloudError(message or "WhatsApp API request failed", status_code=exc.code, response=parsed) from exc
        except urllib.error.URLError as exc:
            raise WhatsAppCloudError(str(exc)) from exc

        messages = body.get("messages") or []
        if not messages or not messages[0].get("id"):
            raise WhatsAppCloudError("WhatsApp API did not return a message id", response=body)

        return WhatsAppSendResult(
            message_id=messages[0]["id"],
            recipient=recipient,
            template_name=template,
        )


def get_whatsapp_client() -> WhatsAppCloudClient:
    return WhatsAppCloudClient(get_settings())
