"""
Abstract provider interface for Velocity Comms.
"""

import os
from abc import ABC, abstractmethod
from typing import Any, Dict, List, Optional


class CommsProvider(ABC):
    def __init__(self, base_url: str, api_key: str, instance_id: Optional[str] = None):
        self.base_url = base_url.rstrip("/")
        self.api_key = api_key
        self.instance_id = instance_id

    @abstractmethod
    async def send_message(self, phone: str, message: str, message_type: str = "text", **kwargs) -> Dict[str, Any]:
        """Send a message. Return provider response dict."""
        ...

    @abstractmethod
    async def normalize_webhook(self, payload: Dict[str, Any]) -> Dict[str, Any]:
        """Convert provider webhook payload to Velocity canonical format."""
        ...

    @abstractmethod
    async def test_connection(self) -> Dict[str, Any]:
        """Test provider connectivity. Return {success, message, account_info}."""
        ...

    async def fetch_templates(self) -> List[Dict[str, Any]]:
        """Optional: fetch message templates."""
        return []

    async def get_media(self, media_id: str) -> Optional[bytes]:
        """Optional: download media bytes."""
        return None

    async def send_template(self, phone: str, template_name: str, language: str, components: Optional[List] = None) -> Dict[str, Any]:
        """Optional: send a template message."""
        raise NotImplementedError("Templates not supported by this provider.")


class MockProvider(CommsProvider):
    """Mock provider for local development and UI previews."""

    async def send_message(self, phone: str, message: str, message_type: str = "text", **kwargs) -> Dict[str, Any]:
        return {
            "success": True,
            "provider": "mock",
            "external_message_id": f"mock-{os.urandom(4).hex()}",
            "status": "sent",
        }

    async def normalize_webhook(self, payload: Dict[str, Any]) -> Dict[str, Any]:
        return payload

    async def test_connection(self) -> Dict[str, Any]:
        return {
            "success": True,
            "message": "Mock provider is always healthy.",
            "account_info": {"mode": "mock"},
        }
