import msal
import requests
import os
import logging
from dotenv import load_dotenv

# 🔹 Carregar variáveis do .env
load_dotenv()

# Configurações do Microsoft Graph API
CLIENT_ID = os.getenv("EMAIL_CLIENT_ID")
CLIENT_SECRET = os.getenv("EMAIL_CLIENT_SECRET")
TENANT_ID = os.getenv("EMAIL_TENANT_ID")
EMAIL_SENDER = os.getenv("EMAIL_SENDER")  # Usuário que enviará o e-mail

AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}"
SCOPE = ["https://graph.microsoft.com/.default"]
GRAPH_API_URL = "https://graph.microsoft.com/v1.0/users"

# 🔹 Configuração do Logger
LOG_FILE = "email_debug.log"
logging.basicConfig(
    filename=LOG_FILE,
    level=logging.DEBUG,  # Captura todos os níveis: DEBUG, INFO, WARNING, ERROR e CRITICAL
    format="%(asctime)s - %(levelname)s - %(message)s",
)

def get_access_token():
    """ Obtém um token de acesso OAuth2 da Microsoft Graph API """
    try:
        logging.info("🔵 Solicitando token de acesso ao Microsoft Graph API...")
        app = msal.ConfidentialClientApplication(
            CLIENT_ID,
            authority=AUTHORITY,
            client_credential=CLIENT_SECRET
        )
        result = app.acquire_token_for_client(scopes=SCOPE)
        if "access_token" in result:
            logging.info("✅ Token de acesso obtido com sucesso!")
            return result["access_token"]
        else:
            error = result.get("error")
            error_desc = result.get("error_description")
            logging.error(f"❌ Erro ao obter token: {error} - {error_desc}")
            return None
    except Exception as e:
        logging.exception(f"❌ Exceção ao tentar obter token: {e}")
        return None

def check_sent_email(subject, access_token):
    """
    Consulta a caixa de enviados do usuário para verificar se um e-mail com o assunto
    especificado foi realmente enviado.
    """
    url = f"{GRAPH_API_URL}/{EMAIL_SENDER}/mailFolders/SentItems/messages"
    params = {
        "$top": 10,                   # Consulta os 10 e-mails mais recentes
        "$orderby": "sentDateTime desc"  # Ordena por data de envio decrescente
    }
    headers = {
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "application/json"
    }
    try:
        response = requests.get(url, headers=headers, params=params)
        logging.debug(f"🔹 Verificando mensagens enviadas: Código {response.status_code} | Conteúdo: {response.text}")
        if response.status_code == 200:
            messages = response.json().get("value", [])
            for message in messages:
                if message.get("subject") == subject:
                    logging.info(f"✅ Verificado no Azure: O e-mail com o assunto '{subject}' foi encontrado na caixa de enviados.")
                    return True
            logging.error(f"❌ E-mail com o assunto '{subject}' não foi encontrado na caixa de enviados.")
            return False
        else:
            logging.error(f"❌ Erro ao consultar a caixa de enviados: Código {response.status_code}, Resposta: {response.text}")
            return False
    except Exception as e:
        logging.exception(f"❌ Exceção ao tentar consultar a caixa de enviados: {e}")
        return False

def send_email(subject, body, recipients):
    """ Envia um e-mail via Microsoft Graph API e registra os passos no log """
    access_token = get_access_token()
    if not access_token:
        logging.error("❌ Falha ao obter token de acesso. Cancelando envio de e-mail.")
        return False

    url = f"{GRAPH_API_URL}/{EMAIL_SENDER}/sendMail"
    headers = {
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "application/json"
    }

    # Se os destinatários estiverem em uma string separada por vírgulas, converte para lista
    if isinstance(recipients, str):
        recipients = [email.strip() for email in recipients.split(",")]

    email_data = {
        "message": {
            "subject": subject,
            "body": {
                "contentType": "HTML",
                "content": body
            },
            "toRecipients": [{"emailAddress": {"address": recipient}} for recipient in recipients]
        },
        "saveToSentItems": True  # Para salvar o e-mail enviado na caixa de enviados do remetente
    }

    try:
        logging.info(f"📤 Enviando e-mail para: {', '.join(recipients)} | Assunto: {subject}")
        logging.debug(f"🔹 Payload do e-mail: {email_data}")

        response = requests.post(url, headers=headers, json=email_data)
        logging.debug(f"🔹 Resposta da API: Código {response.status_code} | Conteúdo: {response.text}")

        if response.status_code == 202:
            logging.info("✅ E-mail enviado com sucesso!")
            # Após o envio, consulta a caixa de enviados para confirmar
            if check_sent_email(subject, access_token):
                logging.info("✅ A verificação no Azure confirmou que o e-mail foi enviado.")
            else:
                logging.error("❌ A verificação no Azure não encontrou o e-mail na caixa de enviados.")
            return True
        else:
            logging.error(f"❌ Erro ao enviar e-mail. Código: {response.status_code}, Resposta: {response.text}")
            return False
    except Exception as e:
        logging.exception(f"❌ Exceção ao tentar enviar e-mail: {e}")
        return False

# Exemplo de uso para teste
if __name__ == "__main__":
    subject = "Teste de E-mail via Microsoft Graph API"
    body = "<h3>Este é um teste de envio de e-mail.</h3>"
    # Destinatários de teste
    recipients = "glassto@gmail.com, fabiano.alves@grfgraph.com.br"

    if send_email(subject, body, recipients):
        print("E-mail enviado com sucesso e verificado na caixa de enviados!")
    else:
        print("Falha no envio ou verificação do e-mail. Confira os logs em 'email_debug.log'.")
