"""Twilio SMS plugin -- implements MessagingProvider for direct SMS via Twilio.

Decoupled from Zo's messaging agent. Uses Twilio REST API for SMS
send/receive so Vastian controls its own messaging channel.

Requires in .env:
    TWILIO_ACCOUNT_SID=ACxxxx
    TWILIO_AUTH_TOKEN=xxxx
    TWILIO_FROM_NUMBER=+1xxxxxxxxxx
    TWILIO_TO_NUMBER=+1xxxxxxxxxx  (default recipient, your phone)
"""

from __future__ import annotations

import logging
import os
from datetime import UTC, datetime
from typing import Any

logger = logging.getLogger(__name__)


class TwilioSmsProvider:
    """MessagingProvider implementation using Twilio REST API.

    Send-only initially. Pull inbox via Twilio webhook (future).
    """

    def __init__(
        self,
        account_sid: str = "",
        auth_token: str = "",
        from_number: str = "",
        to_number: str = "",
    ) -> None:
        self.account_sid = account_sid or os.environ.get("TWILIO_ACCOUNT_SID", "")
        self.auth_token = auth_token or os.environ.get("TWILIO_AUTH_TOKEN", "")
        self.from_number = from_number or os.environ.get("TWILIO_FROM_NUMBER", "")
        self.to_number = to_number or os.environ.get("TWILIO_TO_NUMBER", "")
        self._configured = bool(self.account_sid and self.auth_token and self.from_number)

    @property
    def is_configured(self) -> bool:
        return self._configured

    async def send_sms(self, body: str, to: str | None = None) -> dict[str, Any]:
        """Send an SMS via Twilio REST API (no SDK needed)."""
        if not self._configured:
            return {
                "ok": False,
                "error": "Twilio not configured. Set TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM_NUMBER in .env",
            }

        recipient = to or self.to_number
        if not recipient:
            return {
                "ok": False,
                "error": "No recipient phone number. Set TWILIO_TO_NUMBER in .env or pass 'to' param.",
            }

        url = f"https://api.twilio.com/2010-04-01/Accounts/{self.account_sid}/Messages.json"
        payload = {
            "From": self.from_number,
            "To": recipient,
            "Body": body[:1600],  # Twilio limit
        }

        try:
            import httpx

            async with httpx.AsyncClient() as client:
                resp = await client.post(
                    url,
                    data=payload,
                    auth=(self.account_sid, self.auth_token),
                    timeout=15,
                )
                data = resp.json()
                if resp.status_code in (200, 201):
                    return {
                        "ok": True,
                        "message_id": data.get("sid", ""),
                        "status": data.get("status", "queued"),
                    }
                else:
                    error_msg = data.get("message", resp.text[:200])
                    logger.error("Twilio SMS failed: %s", error_msg)
                    return {"ok": False, "error": error_msg}
        except ImportError:
            return {"ok": False, "error": "httpx not installed (required for Twilio)"}
        except Exception as e:
            logger.error("Twilio SMS send error: %s", e)
            return {"ok": False, "error": str(e)}

    async def send_email(
        self,
        subject: str,
        body: str,
        to: str | None = None,
        attachments: list[str] | None = None,
    ) -> dict[str, Any]:
        """Twilio provider is SMS-only. Delegate email to another provider."""
        return {
            "ok": False,
            "error": "Twilio provider is SMS-only. Use another provider for email.",
        }

    async def pull_inbox(self) -> list[dict[str, Any]]:
        """Pull recent inbound SMS from Twilio message list API."""
        if not self._configured:
            return []

        url = f"https://api.twilio.com/2010-04-01/Accounts/{self.account_sid}/Messages.json"
        params = {
            "To": self.from_number,  # messages sent TO our Twilio number
            "PageSize": "20",
        }

        try:
            import httpx

            async with httpx.AsyncClient() as client:
                resp = await client.get(
                    url,
                    params=params,
                    auth=(self.account_sid, self.auth_token),
                    timeout=15,
                )
                if resp.status_code != 200:
                    return []
                data = resp.json()
                messages = []
                for msg in data.get("messages", []):
                    messages.append(
                        {
                            "id": msg.get("sid", ""),
                            "source": msg.get("from", ""),
                            "content": msg.get("body", ""),
                            "timestamp": msg.get("date_sent", datetime.now(UTC).isoformat()),
                            "type": "sms",
                        }
                    )
                return messages
        except Exception as e:
            logger.error("Twilio inbox pull failed: %s", e)
            return []

    async def get_contacts(self) -> list[dict[str, str]]:
        """Return the default contact (user's phone number)."""
        if self.to_number:
            return [{"name": "User", "phone": self.to_number}]
        return []


def register() -> None:
    """Register this plugin with the loader."""
    from vastian.loader import register as loader_register

    loader_register("twilio_sms", TwilioSmsProvider)
