import httpx
from typing import List, Dict, Any, Optional
import json
import base64
import os



# ... (imports existentes no topo) ...
from datetime import datetime, timedelta
import asyncio # <-- NOVO: Para agendamento assíncrono
from apscheduler.schedulers.asyncio import AsyncIOScheduler # <-- NOVO: Agendador


# --- NOVO: Scheduler para agendar a limpeza de sessões ---
scheduler = AsyncIOScheduler()
# Iniciar o scheduler quando o aplicativo iniciar (isso será feito no main.py ou api/webhook.py)

# ... (carregamento de chaves e outras funções) ...

# --- Variáveis Globais para Gerenciamento de Sessão (APENAS PARA TESTE) ---
# Em produção, isso seria um banco de dados
ACTIVE_SESSIONS = {} # Dicionário para armazenar sessões ativas
SESSION_TIMEOUT_SECONDS = 120 # 5 minutos (5 * 60 segundos)
# --- FIM DAS VARIÁVEIS GLOBAIS DE SESSÃO ---



# Importações para criptografia
from cryptography.hazmat.primitives.asymmetric import padding # <-- Esta linha está correta!
from cryptography.hazmat.primitives import hashes # <-- Esta importação está correta!
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.serialization import load_pem_private_key, load_pem_public_key
from cryptography.hazmat.backends import default_backend


from config import WHATSAPP_ACCESS_TOKEN, WHATSAPP_PHONE_NUMBER_ID, VERIFY_TOKEN, FLOW_PRIVATE_KEY_PASSWORD # <-- ADICIONADO
# Importe Message para type hinting. Certifique-se que webhook_model.py está correto primeiro!
from models.webhook_model import Message, TextMessage, ButtonMessage, InteractiveMessage, ListReply # Adicione os modelos necessários

FLOW_PRIVATE_KEY_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../private.pem')

FLOW_PRIVATE_KEY = None # Garante que a variável começa como None antes do try/except

# --- NOVOS PRINTS PARA DEPURACAO DA CHAVE PRIVADA ---
print("\n--- INICIANDO DEPURACAO DE CARREGAMENTO DE CHAVE PRIVADA DO FLOW ---")
print(f"DEBUG: Caminho configurado para a chave privada: {FLOW_PRIVATE_KEY_PATH}")

# Verifica se o arquivo existe antes de tentar abrir
if not os.path.exists(FLOW_PRIVATE_KEY_PATH):
    print(f"DEBUG: ATENÇÃO: Arquivo da chave privada NÃO ENCONTRADO em {FLOW_PRIVATE_KEY_PATH} antes de tentar carregar.")
else:
    print(f"DEBUG: Arquivo da chave privada ENCONTRADO em {FLOW_PRIVATE_KEY_PATH}. Tentando ler...")
    try:
        # Tenta ler o conteúdo do arquivo para ter certeza que é acessível e não vazio
        with open(FLOW_PRIVATE_KEY_PATH, "rb") as key_file_check:
            key_content_check = key_file_check.read(100) # Lê apenas os primeiros 100 bytes
            print(f"DEBUG: Primeiros 100 bytes do arquivo da chave (preview): {key_content_check!r}...")
            if not key_content_check:
                print("DEBUG: ATENÇÃO: Arquivo da chave privada está VAZIO.")
    except Exception as e_check:
        print(f"DEBUG: ERRO ao tentar PRÉ-LER o arquivo da chave: {type(e_check).__name__}: {e_check}")

print(f"DEBUG: Valor de FLOW_PRIVATE_KEY_PASSWORD (carregado do .env/config): '{FLOW_PRIVATE_KEY_PASSWORD}' (Tipo: {type(FLOW_PRIVATE_KEY_PASSWORD).__name__})")
# --- FIM DOS PRINTS DE DEPURACAO DA CHAVE PRIVADA ---


try:
    with open(FLOW_PRIVATE_KEY_PATH, "rb") as key_file:
        key_content = key_file.read()
        
        # CONDIÇÃO CRÍTICA: Use a senha se ela existir, ou None se a chave não tiver senha
        password_to_use = FLOW_PRIVATE_KEY_PASSWORD.encode('utf-8') if FLOW_PRIVATE_KEY_PASSWORD else None

        print(f"DEBUG: Senha que será usada para carregar a chave: {'(presente)' if password_to_use else '(ausente/None)'}")

        FLOW_PRIVATE_KEY = load_pem_private_key(
            key_content,
            password=password_to_use, # <<< ALTERADO PARA USAR A SENHA
            backend=default_backend()
        )
    print(f"✅ Chave privada do Flow carregada de: {FLOW_PRIVATE_KEY_PATH}")
except FileNotFoundError:
    print(f"❌ ERRO: Chave privada do Flow não encontrada em {FLOW_PRIVATE_KEY_PATH}. Verifique o caminho e as permissões.")
    FLOW_PRIVATE_KEY = None
except Exception as e:
    # A exceção agora provavelmente será relacionada à senha se o arquivo for encontrado
    # OU se o formato da chave está errado para o password=None/password='suasenha'
    print(f"❌ ERRO ao carregar chave privada do Flow: {type(e).__name__}: {e}. Verifique se a senha está correta ou se a chave não tem senha. Conteúdo da chave (primeiros 50 bytes): {key_content[:50]!r}...")
    FLOW_PRIVATE_KEY = None
    
WHATSAPP_FLOW_PUBLIC_KEY_META_FOR_ENCRYPTION_OF_AES = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsFw96WUer6yyZLQFkUNS
Vkv++EEKVVVXca3TcCJqR9aaOepiyKuUT0Il8ctdaZHaTFeEQnM82xbaijEATtGv
qmX+zZRnMnRbI63GZm9QM3pnAbs/iXji5PfLbD5AGt8vDUyldlwGu+2e3PHWHPM2
MKR/+yHEEmgXWWkCYzgdhwIbsaGQNFdOXykfVpdQLt8237E1VEDEebEP3GlUagvo
7k+NQQ+tDHNfAeQjcIHiTCPE39hSFdH7W413HDiu/0sX02ATv+QCppovDBboQdL4
OP4nbnvbRn7HHIFIPskpkm5dPfRuDrejb/Q72c1FcuALBAPFpJYCsjUM3JSfa854
IwIDAQAB-----END PUBLIC KEY-----""" # <<< COLOQUE A SUA CHAVE PÚBLICA (DO public_flow_key.pem) AQUI! <<<

try:
    WHATSAPP_FLOW_PUBLIC_KEY_META_FOR_ENCRYPTION_OF_AES_OBJECT = load_pem_public_key(
        WHATSAPP_FLOW_PUBLIC_KEY_META_FOR_ENCRYPTION_OF_AES.encode('utf-8'),
        backend=default_backend()
    )
    print("✅ Chave pública da Meta (assumida) para criptografia de retorno (Flows) carregada.")
except Exception as e:
    print(f"❌ ERRO ao carregar chave pública da Meta para Flow (para criptografia de retorno): {e}")
    WHATSAPP_FLOW_PUBLIC_KEY_META_FOR_ENCRYPTION_OF_AES_OBJECT = None

def decrypt_flow_request_data(
    encrypted_flow_data_b64: str,
    encrypted_aes_key_b64: str,
    initial_vector_b64: str
) -> Dict[str, Any]: # << AQUI ESTÁ A MUDANÇA: AGORA RETORNA UM DICIONÁRIO COMPLETO
    """
    Descriptografa os dados de requisição recebidos de um Flow do WhatsApp.
    Retorna os dados descriptografados, a chave AES e o IV.
    """
    if not FLOW_PRIVATE_KEY:
        raise ValueError("Chave privada do Flow não carregada. Não é possível descriptografar a requisição.")

    flow_data = base64.b64decode(encrypted_flow_data_b64)
    iv = base64.b64decode(initial_vector_b64)

    encrypted_flow_data_body = flow_data[:-16]
    encrypted_flow_data_tag = flow_data[-16:]

    encrypted_aes_key = base64.b64decode(encrypted_aes_key_b64)
    aes_key = FLOW_PRIVATE_KEY.decrypt(
        encrypted_aes_key,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

    decryptor = Cipher(
        algorithms.AES(aes_key),
        modes.GCM(iv, encrypted_flow_data_tag),
        backend=default_backend()
    ).decryptor()
    
    decrypted_data_bytes = decryptor.update(encrypted_flow_data_body) + decryptor.finalize()
    decrypted_data = json.loads(decrypted_data_bytes.decode("utf-8"))
    
    # Retorna os dados, a chave AES e o IV para uso na resposta
    return {
        "decrypted_payload": decrypted_data,
        "aes_key": aes_key,
        "initial_vector": iv
    }


def encrypt_flow_response_data(response_data: Dict[str, Any], aes_key: bytes, initial_vector: bytes) -> str:
    """
    Criptografa os dados de resposta do Flow para enviar ao WhatsApp.
    Usa a chave AES e o IV (invertido) recebidos na solicitação original.
    Retorna a string completa codificada em Base64.
    """
    # Nenhuma chave pública RSA é usada AQUI para criptografar a AES_KEY.
    # A AES_KEY e o IV são passados da requisição original.

    # 1. Preparar initialization vector para resposta (invertendo bits do IV original)
    flipped_iv = bytearray()
    for byte in initial_vector:
        flipped_iv.append(byte ^ 0xFF) # XOR com 0xFF para inverter bits

    # 2. Criptografar o payload de resposta (JSON) usando AES-GCM
    plaintext_bytes = json.dumps(response_data).encode('utf-8')

    encryptor = Cipher(algorithms.AES(aes_key), modes.GCM(flipped_iv), backend=default_backend()).encryptor()
    encrypted_data_bytes = encryptor.update(plaintext_bytes) + encryptor.finalize()
    tag = encryptor.tag # Tag de autenticação do GCM

    # 3. CONSTRUIR A STRING FINAL Base64:
    # A Meta espera o IV e o TAG concatenados ao final dos dados criptografados,
    # e então TUDO isso é Base64 codificado. O exemplo Django mostrou isso implicitamente.
    
    # Payload final em bytes: encrypted_data_bytes + flipped_iv + tag
    # ATENÇÃO: O exemplo Django concatena o IV no payload final, mas a documentação
    # da Meta para AES-GCM geralmente não o faz, ela espera que o IV seja separado no cabeçalho.
    # No entanto, a documentação que você me passou disse "append authentication tag
    # generated during encryption to the end of the encryption result; encode the whole output as base64 string".
    #
    # Vamos seguir o exemplo Django para a resposta. O exemplo Django para `encrypt_response`
    # retorna base64(encryptor.update(...) + encryptor.finalize() + encryptor.tag).
    # Ele NÃO inclui a chave AES criptografada aqui, porque a Meta já tem a chave AES.
    
    # O retorno deve ser SOMENTE o dado criptografado + tag, Base64 codificado.
    # O IV e a chave AES são gerenciados pela Meta.
    
    # A ÚLTIMA TENTATIVA DA METAMORA: Retornar a STRING Base64 pura dos dados criptografados + tag
    # (sem o JSON aninhado que estávamos construindo)
    
    # A resposta final é apenas a CONCATENAÇÃO dos dados criptografados e o tag, codificado em Base64.
    final_payload_bytes = encrypted_data_bytes + tag # Dados criptografados + Tag
    base64_encoded_final_response = base64.b64encode(final_payload_bytes).decode('utf-8')
    
    return base64_encoded_final_response




# --- Funções de Gerenciamento de Sessão ---

def get_session_state(sender_id: str) -> Optional[Dict[str, Any]]:
    return ACTIVE_SESSIONS.get(sender_id)

async def clean_session_and_notify(sender_id: str): # <-- FUNÇÃO ASSÍNCRONA PARA LIMPAR E NOTIFICAR
    """
    Função assíncrona que limpa a sessão e envia a mensagem de timeout.
    Chamada pelo scheduler.
    """
    if sender_id in ACTIVE_SESSIONS: # Verifica se a sessão ainda está ativa (não foi atualizada antes do timeout)
        timeout_message = "Sua sessão foi encerrada por inatividade. Por favor, envie uma nova mensagem para iniciar um novo atendimento. 😊"
        print(f"DEBUG_SESSION: Enviando mensagem de timeout para {sender_id}.")
        await send_text_message(sender_id, timeout_message) # <-- CHAMA A FUNÇÃO DE ENVIO

        del ACTIVE_SESSIONS[sender_id]
        print(f"DEBUG_SESSION: Sessão para {sender_id} encerrada/limpa pelo agendador.")
    else:
        print(f"DEBUG_SESSION: Sessão para {sender_id} já limpa ou atualizada antes do agendamento.")

def start_or_update_session(sender_id: str):
    """
    Inicia uma nova sessão para o usuário ou atualiza o timestamp da última atividade.
    Agenda ou reagenda a tarefa de limpeza.
    """
    current_time = datetime.now()
    ACTIVE_SESSIONS[sender_id] = {
        "last_activity_time": current_time,
        "current_state": "INICIO" # Ou qualquer estado inicial padrão
    }
    print(f"DEBUG_SESSION: Sessão para {sender_id} iniciada/atualizada em {current_time.strftime('%Y-%m-%d %H:%M:%S')}.")

    # Remover tarefa agendada anterior para esta sessão, se houver
    job_id = f"session_clean_{sender_id}"
    if scheduler.get_job(job_id):
        scheduler.remove_job(job_id)
        print(f"DEBUG_SESSION: Tarefa de limpeza anterior para {sender_id} cancelada.")
    
    # Agendar nova tarefa de limpeza para esta sessão
    scheduler.add_job(
        clean_session_and_notify,
        'date', # Agendamento único para uma data/hora específica
        run_date=current_time + timedelta(seconds=SESSION_TIMEOUT_SECONDS),
        args=[sender_id],
        id=job_id,
        replace_existing=True # Para garantir que não haja duplicatas, embora remove_job já ajude
    )
    print(f"DEBUG_SESSION: Tarefa de limpeza para {sender_id} agendada para {current_time + timedelta(seconds=SESSION_TIMEOUT_SECONDS)}.")





# --- Lógicas de Tratamento de Mensagens Recebidas (Funções Auxiliares) ---
# Estas funções contêm a lógica de como seu bot irá interagir.

# Esta função precisa ser definida no arquivo!
async def handle_message_type(message: Message):
    sender_id = message.from_

    # 1. Iniciar ou atualizar a sessão para o remetente atual
    #    Isso vai automaticamente agendar/reagendar a limpeza.
    start_or_update_session(sender_id) # Esta função agora agenda a limpeza!

    # 2. Recuperar o estado da sessão (se houver, para uso futuro com grafos)
    session_data = get_session_state(sender_id)
    if session_data:
        print(f"DEBUG_SESSION: Estado atual da sessão para {sender_id}: {session_data['current_state']}")
    else:
        # Isso não deveria acontecer se start_or_update_session funcionou
        print(f"DEBUG_SESSION: Sessão para {sender_id} não encontrada após start_or_update_session (possível erro).")

    if message.type == 'text' and message.text:
        await handle_text_message(sender_id, message.text.body) # Passe sender_id
    elif message.type == 'button' and message.button:
        await handle_button_response(sender_id, message.button.payload) # Passe sender_id
    elif message.type == 'interactive' and message.interactive:
        if message.interactive.type == 'list_reply' and message.interactive.list_reply:
            await handle_list_response(sender_id, message.interactive.list_reply.id, message.interactive.list_reply.title) # Passe sender_id
        elif message.interactive.type == 'button_reply' and message.interactive.button_reply:
            await handle_button_response(sender_id, message.interactive.button_reply.payload) # Passe sender_id
        else:
            print(f"   Tipo interativo desconhecido recebido: {message.interactive.type}")
            await send_text_message(sender_id, "Desculpe, não entendi essa interação interativa.")
    elif message.type == 'image':
        print('   Recebi uma imagem!')
        await send_text_message(sender_id, "Que legal! Recebi sua imagem. No momento, só consigo processar texto e interações.")
    else:
        print(f"   Tipo de mensagem não suportado: {message.type}")
        await send_text_message(sender_id, "Desculpe, não entendi o tipo de mensagem que você enviou.")


async def handle_text_message(sender_id: str, text: str):
    lower_text = text.lower()
    if lower_text != "" :
        await send_text_message(sender_id, "Olá! Você iniciou o Consultme. Escolha uma das opções de consulta no menu abaixo:")
        await send_interactive_menu(sender_id) # Chama a função para enviar um menu interativo
    elif 'menu' in lower_text:
        await send_interactive_menu(sender_id)
    elif 'cadastro' in lower_text:
        await send_text_message(sender_id, "Para iniciar seu cadastro, por favor, me diga seu nome completo:")
        # Implemente lógica para salvar o estado do usuário aqui (ex: em um DB)
    elif 'ajuda' in lower_text:
        await send_text_message(sender_id, "Posso te guiar com as funcionalidades principais. Escolha uma opção do menu ou digite uma pergunta.")
        await send_interactive_menu(sender_id)
    else:
        await send_text_message(sender_id, f"Recebi sua mensagem: \"{text}\". Parece que não entendi bem. Você pode digitar 'menu' para ver as opções disponíveis ou 'ajuda'.")

async def handle_button_response(sender_id: str, payload: str):
    response_text = ''
    if payload == 'OPTION_AGENDAR':
        response_text = "Certo! Para agendar um serviço, qual serviço você precisa e a data/hora preferida?"
    elif payload == 'OPTION_STATUS':
        response_text = "Para verificar o status de seu pedido, informe o número do seu pedido."
    elif payload == 'OPTION_FALAR_ATENDENTE':
        response_text = "Encaminhando você para um de nossos atendentes. Aguarde, por favor."
    else:
        response_text = "Não entendi a opção de botão selecionada. Tente novamente ou digite 'menu'."
    await send_text_message(sender_id, response_text)

async def handle_list_response(sender_id: str, list_id: str, list_title: str):
    response_text = ''
    if list_id == 'item_reparo_geral':
        response_text = f"Você selecionou \"{list_title}\". Qual o problema específico que você precisa de reparo?"
    elif list_id == 'item_instalacao':
        response_text = f"Você selecionou \"{list_title}\". Qual tipo de instalação você precisa?"
    elif list_id == 'item_duvidas':
        response_text = f"Você selecionou \"{list_title}\". Por favor, digite sua pergunta."
    elif list_id == 'item_reclamacoes':
        response_text = f"Você selecionou \"{list_title}\". Por favor, descreva o problema em detalhes."
    else:
        response_text = "Opção de lista não reconhecida. Tente novamente ou digite 'menu'."
    await send_text_message(sender_id, response_text)

# --- Funções de Envio de Mensagens para o WhatsApp ---
# Estas funções fazem as chamadas à API da Meta para enviar mensagens.

async def send_text_message(to: str, text: str):
    url = f"https://graph.facebook.com/v23.0/{WHATSAPP_PHONE_NUMBER_ID}/messages"
    headers = {
        'Authorization': f'Bearer {WHATSAPP_ACCESS_TOKEN}',
        'Content-Type': 'application/json'
    }
    payload = {
        "messaging_product": "whatsapp",
        "to": to,
        "type": "text",
        "text": {
            "preview_url": False,
            "body": text
        }
    }
    async with httpx.AsyncClient() as client:
        try:
            response = await client.post(url, headers=headers, json=payload)
            response.raise_for_status()
            print("✅ Mensagem de texto enviada com sucesso:", response.json())
        except httpx.HTTPStatusError as e:
            print(f"❌ Erro HTTP ao enviar mensagem de texto: {e.response.status_code} - {e.response.text}")
        except httpx.RequestError as e:
            print(f"❌ Erro de rede ao enviar mensagem de texto: {e}")

async def send_interactive_buttons(to: str, header_text: str, body_text: str, buttons_array: List[Dict[str, str]]):
    url = f"https://graph.facebook.com/v23.0/{WHATSAPP_PHONE_NUMBER_ID}/messages"
    headers = {
        'Authorization': f'Bearer {WHATSAPP_ACCESS_TOKEN}',
        'Content-Type': 'application/json'
    }
    payload = {
        "messaging_product": "whatsapp",
        "to": to,
        "type": "interactive",
        "interactive": {
            "type": "button",
            "header": { "type": "text", "text": header_text },
            "body": { "text": body_text },
            "action": {
                "buttons": [{"type": "reply", "reply": {"id": btn["id"], "title": btn["title"]}} for btn in buttons_array]
            }
        }
    }
    async with httpx.AsyncClient() as client:
        try:
            response = await client.post(url, headers=headers, json=payload)
            response.raise_for_status()
            print("✅ Mensagem com botões enviada com sucesso:", response.json())
        except httpx.HTTPStatusError as e:
            print(f"❌ Erro HTTP ao enviar mensagem com botões: {e.response.status_code} - {e.response.text}")
        except httpx.RequestError as e:
            print(f"❌ Erro de rede ao enviar mensagem com botões: {e}")

async def send_interactive_list(to: str, header_text: str, body_text: str, button_title: str, sections_array: List[Dict[str, Any]]):
    url = f"https://graph.facebook.com/v23.0/{WHATSAPP_PHONE_NUMBER_ID}/messages"
    headers = {
        'Authorization': f'Bearer {WHATSAPP_ACCESS_TOKEN}',
        'Content-Type': 'application/json'
    }
    payload = {
        "messaging_product": "whatsapp",
        "to": to,
        "type": "interactive",
        "interactive": {
            "type": "list",
            "header": { "type": "text", "text": header_text },
            "body": { "text": body_text },
            "action": {
                "button": button_title,
                "sections": [
                    {
                        "title": section["title"],
                        "rows": [{"id": row["id"], "title": row["title"], "description": row.get("description", "")} for row in section["rows"]]
                    } for section in sections_array
                ]
            }
        }
    }
    async with httpx.AsyncClient() as client:
        try:
            response = await client.post(url, headers=headers, json=payload)
            response.raise_for_status()
            print("✅ Mensagem de lista enviada com sucesso:", response.json())
        except httpx.HTTPStatusError as e:
            print(f"❌ Erro HTTP ao enviar mensagem de lista: {e.response.status_code} - {e.response.text}")
        except httpx.RequestError as e:
            print(f"❌ Erro de rede ao enviar mensagem de lista: {e}")

async def mark_message_as_read(message_id: str):
    url = f"https://graph.facebook.com/v23.0/{WHATSAPP_PHONE_NUMBER_ID}/messages"
    headers = {
        'Authorization': f'Bearer {WHATSAPP_ACCESS_TOKEN}',
        'Content-Type': 'application/json'
    }
    payload = {
        "messaging_product": "whatsapp",
        "status": "read",
        "message_id": message_id
    }
    async with httpx.AsyncClient() as client:
        try:
            response = await client.post(url, headers=headers, json=payload)
            response.raise_for_status()
        except httpx.HTTPStatusError as e:
            print(f"❌ Erro HTTP ao marcar mensagem {message_id} como lida: {e.response.status_code} - {e.response.text}")
        except httpx.RequestError as e:
            print(f"❌ Erro de rede ao marcar mensagem {message_id} como lida: {e}")

# --- Função de Exemplo para Enviar um Menu Interativo ---
async def send_interactive_menu(to: str):
    buttons = [
        {"id": 'OPTION_AGENDAR', "title": 'Total do CP'},
        {"id": 'OPTION_STATUS', "title": 'Total das suas Lojas'},
        {"id": 'OPTION_FALAR_ATENDENTE', "title": 'De uma Loja'}
    ]
    await send_interactive_buttons(to, "Menu Principal", "Escolha a Dimensão das Lojas que você quer visulizar o indicador:", buttons)


async def send_whatsapp_flow(to: str, flow_id: str, flow_cta: str, screen: str = "welcome_screen") -> Dict[str, Any]:
    url = f"https://graph.facebook.com/v18.0/{WHATSAPP_PHONE_NUMBER_ID}/messages" 
    headers = {
        'Authorization': f'Bearer {WHATSAPP_ACCESS_TOKEN}',
        'Content-Type': 'application/json'
    }

    payload = {
        "recipient_type": "individual", # <-- ADICIONADO: Conforme a documentação
        "messaging_product": "whatsapp",
        "to": to,
        "type": "interactive",
        "interactive": {
            "type": "flow",
            "header": {
                "type": "text",
                "text": "Preencha seu Cadastro"
            },
            "body": {
                "text": "Clique no botão abaixo para preencher o formulário de cadastro."
            },
            "footer": {
                "text": "Consultme - Seu parceiro digital"
            },
            "action": {
                "name": "flow",
                "parameters": {
                    "flow_id": flow_id, # Usando flow_id (geralmente melhor que flow_name)
                    "flow_cta": flow_cta,
                    # --- ATENÇÃO: MUDAR PARA flow_message_version: "3" (STRING LITERAL "3") ---
                    # Já que o exemplo da documentação é v18.0 com "3", vamos seguir esse exato
                    "flow_message_version": "3" # <--- ALTERE ESTA LINHA PARA "3"
                }
            }
        }
    }
    
    # ... (restante da função, incluindo DEBUG PRINTS e try/except) ...
    print(f"DEBUG_FLOW: Payload a ser enviado para o Flow API: {json.dumps(payload, indent=2)}") # Verifique o payload final no log
    async with httpx.AsyncClient() as client:
        try:
            response = await client.post(url, headers=headers, json=payload)
            response.raise_for_status()
            print("✅ Flow enviado com sucesso:", response.json())
            return {"status": "success", "data": response.json()}
        except httpx.HTTPStatusError as e:
            print(f"❌ ERRO HTTP ao enviar Flow (Status: {e.response.status_code}, Detalhe: {e.response.text}): {e}")
            # print(f"DEBUG_FLOW_ERROR_RESPONSE: {e.response.json()}") # Descomente para ver o erro JSON completo da Meta
            return {"status": "error", "message": e.response.text, "code": e.response.status_code}
        except httpx.RequestError as e:
            print(f"❌ ERRO de rede ao enviar Flow: {e}")
            return {"status": "error", "message": str(e), "code": 500}
        except Exception as e:
            print(f"❌ ERRO INESPERADO ao enviar Flow: {type(e).__name__}: {e}")
            return {"status": "error", "message": f"Erro inesperado: {str(e)}", "code": 500}
# ... (send_interactive_menu, handle_button_response, etc.) .