from __future__ import annotations

import re
from typing import TYPE_CHECKING

from ..errors import ValidationError
from ..objects.message import Message
from ..objects.list_response import ListResponse

if TYPE_CHECKING:
    from ..connection import Connection

VALID_TYPES = ("text", "template", "image", "video", "audio", "document", "interactive")
PHONE_PATTERN = re.compile(r"^\+\d{1,15}$")


class BusinessMessages:
    def __init__(self, *, connection: Connection, account_id: str):
        self._connection = connection
        self._account_id = account_id

    def list(self, *, errors_only: bool = False) -> ListResponse[Message]:
        path = self._base_path
        if errors_only:
            path += "?errors_only=true"
        response = self._connection.get(path)
        data = [Message(m) for m in (response.get("data") or [])]
        return ListResponse(data=data, meta=response.get("meta", {}))

    def retrieve(self, message_id: str) -> Message:
        response = self._connection.get(f"{self._base_path}/{message_id}")
        return Message(response["data"])

    def create(self, *, to: str, message_type: str | None = None, content: str | None = None,
               template_name: str | None = None, template_language: str | None = None,
               message_metadata: dict | None = None) -> Message:
        _validate_phone(to)
        resolved_type = message_type or ("text" if content else None)
        _validate_type(resolved_type)

        body = {"to": to}
        if message_type:
            body["message_type"] = message_type
        if content:
            body["content"] = content
        if template_name:
            body["template_name"] = template_name
        if template_language:
            body["template_language"] = template_language
        if message_metadata:
            body["message_metadata"] = message_metadata

        response = self._connection.post(self._base_path, {"message": body})
        return Message(response["data"])

    @property
    def _base_path(self) -> str:
        return f"/business_accounts/{self._account_id}/messages"


def _validate_phone(to: str) -> None:
    if not to:
        raise ValidationError("Phone number is required")
    if not PHONE_PATTERN.match(to):
        raise ValidationError("Invalid phone number format")


def _validate_type(msg_type: str | None) -> None:
    if msg_type and msg_type not in VALID_TYPES:
        raise ValidationError(f"Invalid message type: {msg_type}")
