"""
Twilio SMS notification provider.

Sends SMS messages via the Twilio REST API using httpx (no Twilio SDK dependency).
If TWILIO_ACCOUNT_SID / TWILIO_AUTH_TOKEN are not configured, the send is
skipped and the message is logged instead (stub behaviour).
"""

import logging
from typing import Any, Dict, Optional

import httpx

from src.apps.notifications.providers.base import NotificationProvider
from src.core.config import settings

logger = logging.getLogger(__name__)


class TwilioProvider(NotificationProvider):
    """
    Sends SMS via Twilio REST API using httpx.

    Configuration (settings):
      TWILIO_ACCOUNT_SID  — Twilio Account SID.
      TWILIO_AUTH_TOKEN   — Twilio Auth Token.
      TWILIO_FROM_NUMBER  — Twilio From phone number (E.164 format).
    """

    async def send(
        self,
        recipient: str,
        subject: Optional[str],
        body_text: Optional[str],
        body_html: Optional[str],
        template_vars: Optional[Dict[str, Any]] = None,
    ) -> bool:
        account_sid = settings.TWILIO_ACCOUNT_SID
        auth_token = settings.TWILIO_AUTH_TOKEN
        from_number = settings.TWILIO_FROM_NUMBER

        sms_body = body_text or ""

        if not account_sid or not auth_token:
            logger.info(
                "[SMS STUB] Would send to %s: %s",
                recipient[-4:].rjust(len(recipient), "*"),
                sms_body[:160],
            )
            return True

        try:
            url = (
                f"https://api.twilio.com/2010-04-01/Accounts/{account_sid}/Messages.json"
            )
            async with httpx.AsyncClient() as client:
                response = await client.post(
                    url,
                    auth=(account_sid, auth_token),
                    data={
                        "To": recipient,
                        "From": from_number,
                        "Body": sms_body[:1600],
                    },
                )
                response.raise_for_status()

            logger.info("SMS sent to %s via Twilio", recipient[-4:].rjust(len(recipient), "*"))
            return True

        except Exception as exc:
            logger.error("Twilio SMS send failed for %s: %s", recipient, exc)
            return False
