from typing import List, Optional, Union
from pydantic import BaseModel, Field

class TextMessage(BaseModel):
    body: str

class ButtonMessage(BaseModel):
    # O WhatsApp envia 'id' e 'title' para as respostas de botões,
    # mas o Pydantic pode esperar 'payload' e 'text' se for para envio.
    # Para *recebimento*, precisamos mapear o que vem.
    # O payload que você recebeu mostra 'id' e 'title'.

    # Para a *resposta* de um botão:
    id: str # O ID do botão clicado (que você definiu no seu código)
    title: str # O texto do botão clicado

    # No seu handle_button_response, você espera 'payload'.
    # Isso indica que ButtonMessage foi usado para ENVIO antes.
    # Para *recebimento*, a Meta envia 'id' e 'title'.
    # A melhor prática é ter dois modelos, um para envio e um para recebimento,
    # ou usar aliases condicionais.

    # Pela sua mensagem de erro, o Pydantic (na validação do WebhookEvent)
    # esperava 'payload' e 'text' para o `button_reply`.
    # Vamos renomear e usar aliases para compatibilidade com o que a Meta envia E o que o seu handler espera.
    # O `id` do botão clicado é o `payload` que você espera no seu handler.
    # O `title` do botão clicado é o `text` que você espera.

    # Modelagem para RECEBIMENTO de resposta de botão:
    payload: str = Field(alias="id") # Mapeia 'id' do JSON recebido para 'payload' no Python
    text: str = Field(alias="title") # Mapeia 'title' do JSON recebido para 'text' no Python

class ListReply(BaseModel):
    id: str
    title: str

class InteractiveMessage(BaseModel):
    type: str # 'list_reply', 'button_reply', etc.
    list_reply: Optional[ListReply] = None
    button_reply: Optional[ButtonMessage] = None # Renomeado para button_reply para consistência

class Message(BaseModel): # ESTA É A CLASSE 'Message' QUE ESTAVA FALTANDO!
    from_: str = Field(alias="from") # 'from' é palavra reservada em Python, então usamos alias
    id: str
    timestamp: str
    type: str # 'text', 'image', 'button', 'interactive', etc.
    text: Optional[TextMessage] = None
    button: Optional[ButtonMessage] = None # <-- AQUI! Garanta que está usando o ButtonMessage ajustado
    interactive: Optional[InteractiveMessage] = None
    # Adicione outros tipos de mensagem aqui se precisar processá-los (image, audio, video, etc.)

class Status(BaseModel):
    id: str
    status: str # 'sent', 'delivered', 'read', 'failed'
    timestamp: str
    recipient_id: str
    # Adicione outros campos de status se necessário

class ChangeValue(BaseModel):
    messaging_product: str
    metadata: dict # Pode conter phone_number_id, display_phone_number
    messages: Optional[List[Message]] = None
    statuses: Optional[List[Status]] = None # Para atualizações de status

class Change(BaseModel):
    field: str # 'messages' ou 'statuses'
    value: ChangeValue

class Entry(BaseModel):
    id: str
    changes: List[Change]

class WebhookEvent(BaseModel): # Este é o seu modelo principal do evento
    object: str # 'whatsapp_business_account'
    entry: List[Entry]