#!/usr/bin/env python3
"""
🚨 LIVE EMAIL DELIVERY VERIFICATION SCRIPT 🚨

This script performs a "Live Fire" test to verify that emails actually leave
our infrastructure via SendGrid and arrive at an external, independent mailbox.

Steps:
1. Temporarily configure SendGrid API key (from environment or manual input)
2. Generate unique test email address using Mail7.io disposable email
3. Send a real registration/test email using backend's EmailService
4. Wait for email propagation (10-20 seconds)
5. Query Mail7.io API to verify email arrival
6. Log full headers as proof of delivery
"""

import os
import sys
import time
import uuid
import json
import logging
import asyncio
import httpx
from datetime import datetime
from typing import Dict, Any, Optional

# Add backend to path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'backend'))

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger("fire_drill_email")

# Mail7.io Configuration
MAIL7_API_BASE = "https://api.mail7.io"
# Note: Mail7.io requires API key and secret for inbox access
# These should be obtained from mail7.io dashboard
MAIL7_API_KEY = os.getenv("MAIL7_API_KEY", "")
MAIL7_API_SECRET = os.getenv("MAIL7_API_SECRET", "")

class LiveEmailVerification:
    def __init__(self):
        self.test_id = str(uuid.uuid4())[:8]
        self.test_email = f"sf-audit-{self.test_id}@mail7.io"
        self.security_token = f"SF-VERIFY-{self.test_id}-{int(time.time())}"
        self.results = {}
        
    async def check_mail7_config(self) -> bool:
        """Check if Mail7.io API credentials are configured."""
        if not MAIL7_API_KEY or not MAIL7_API_SECRET:
            logger.error("Mail7.io API credentials not configured!")
            logger.error("Set MAIL7_API_KEY and MAIL7_API_SECRET environment variables")
            logger.error("Get credentials from: https://mail7.io/dashboard")
            return False
        return True
    
    async def send_test_email(self) -> bool:
        """
        Send a test email using the backend's EmailService.
        This requires temporarily configuring SendGrid or production SMTP.
        """
        try:
            # Import email service components
            from app.services.email_manager import EmailManager
            from app.db.session import AsyncSessionLocal
            
            logger.info(f"Sending test email to: {self.test_email}")
            logger.info(f"Security token in body: {self.security_token}")
            
            # Create test variables for email template
            variables = {
                "first_name": "FireDrill",
                "link": f"https://servicefinder.hu/verify?token={self.security_token}",
                "token": self.security_token,
                "test_id": self.test_id,
                "timestamp": datetime.utcnow().isoformat()
            }
            
            # Send email using verification template
            async with AsyncSessionLocal() as db:
                result = await EmailManager.send_email(
                    recipient=self.test_email,
                    template_key="verification",
                    variables=variables,
                    lang="en",
                    db=db
                )
                
            if result:
                logger.info(f"Email sent successfully: {result}")
                self.results["send_result"] = result
                return True
            else:
                logger.error("Email sending failed or returned None")
                return False
                
        except Exception as e:
            logger.error(f"Error sending test email: {e}", exc_info=True)
            return False
    
    async def check_mail7_inbox(self) -> Optional[Dict[str, Any]]:
        """
        Query Mail7.io API to check for incoming email.
        Returns email data if found, None otherwise.
        """
        if not await self.check_mail7_config():
            return None
            
        try:
            # Mail7.io inbox API endpoint
            params = {
                "apikey": MAIL7_API_KEY,
                "apisecret": MAIL7_API_SECRET,
                "to": self.test_email
            }
            
            async with httpx.AsyncClient(timeout=30.0) as client:
                response = await client.get(
                    f"{MAIL7_API_BASE}/inbox",
                    params=params
                )
                
            if response.status_code == 200:
                data = response.json()
                logger.info(f"Mail7 API response: {json.dumps(data, indent=2)}")
                
                if data.get("data"):
                    emails = data["data"]
                    logger.info(f"Found {len(emails)} email(s) in inbox")
                    
                    # Look for our security token in email content
                    for email in emails:
                        subject = email.get("subject", "")
                        text = email.get("text", "")
                        html = email.get("html", "")
                        
                        # Check if our security token is in the email
                        if (self.security_token in subject or 
                            self.security_token in text or 
                            self.security_token in html):
                            logger.info(f"Found matching email with ID: {email.get('id')}")
                            self.results["received_email"] = email
                            return email
                    
                    logger.warning("Email found but security token not matched")
                    self.results["received_email"] = emails[0] if emails else None
                    return emails[0] if emails else None
                else:
                    logger.info("No emails found in inbox yet")
                    return None
            else:
                logger.error(f"Mail7 API error: {response.status_code} - {response.text}")
                return None
                
        except Exception as e:
            logger.error(f"Error checking Mail7 inbox: {e}", exc_info=True)
            return None
    
    async def wait_and_verify(self, max_attempts: int = 6, delay: int = 10) -> bool:
        """
        Wait for email to arrive and verify it.
        Returns True if verification successful.
        """
        logger.info(f"Waiting for email to arrive (checking every {delay} seconds)...")
        
        for attempt in range(1, max_attempts + 1):
            logger.info(f"Attempt {attempt}/{max_attempts}...")
            
            email_data = await self.check_mail7_inbox()
            if email_data:
                logger.info("✅ EMAIL VERIFIED - Successfully received at external mailbox!")
                
                # Log full headers
                headers = email_data.get("headers", {})
                logger.info(f"Email headers: {json.dumps(headers, indent=2)}")
                
                # Save proof of delivery
                self.save_proof_of_delivery(email_data)
                return True
            
            if attempt < max_attempts:
                logger.info(f"Waiting {delay} seconds before next check...")
                await asyncio.sleep(delay)
        
        logger.error("❌ EMAIL NOT RECEIVED - Failed to verify delivery")
        return False
    
    def save_proof_of_delivery(self, email_data: Dict[str, Any]):
        """Save proof of delivery to log file."""
        log_dir = "docs/v201/testing_logs"
        os.makedirs(log_dir, exist_ok=True)
        
        log_file = os.path.join(log_dir, "live_email_success.log")
        
        proof = {
            "timestamp": datetime.utcnow().isoformat(),
            "test_id": self.test_id,
            "test_email": self.test_email,
            "security_token": self.security_token,
            "verification_status": "SUCCESS",
            "email_data": {
                "id": email_data.get("id"),
                "from": email_data.get("from"),
                "to": email_data.get("to"),
                "subject": email_data.get("subject"),
                "received_at": email_data.get("received"),
                "headers": email_data.get("headers", {})
            },
            "full_response": email_data
        }
        
        with open(log_file, "a") as f:
            f.write("\n" + "="*80 + "\n")
            f.write(f"LIVE EMAIL VERIFICATION SUCCESS - {datetime.utcnow()}\n")
            f.write("="*80 + "\n")
            f.write(json.dumps(proof, indent=2))
            f.write("\n")
        
        logger.info(f"Proof of delivery saved to: {log_file}")
    
    def print_summary(self):
        """Print test summary."""
        print("\n" + "="*80)
        print("LIVE EMAIL FIRE DRILL - TEST SUMMARY")
        print("="*80)
        print(f"Test ID: {self.test_id}")
        print(f"Test Email: {self.test_email}")
        print(f"Security Token: {self.security_token}")
        print(f"Timestamp: {datetime.utcnow()}")
        print(f"Mail7 API Configured: {bool(MAIL7_API_KEY and MAIL7_API_SECRET)}")
        
        if "send_result" in self.results:
            print(f"Send Result: {self.results['send_result']}")
        
        if "received_email" in self.results:
            email = self.results["received_email"]
            print(f"Email Received: YES")
            print(f"  From: {email.get('from')}")
            print(f"  Subject: {email.get('subject')}")
            print(f"  Received: {email.get('received')}")
        else:
            print(f"Email Received: NO")
        
        print("="*80)

async def main():
    """Main execution function."""
    print("\n🚀 STARTING LIVE EMAIL DELIVERY VERIFICATION")
    print("="*60)
    
    # Check environment configuration
    sendgrid_key = os.getenv("SENDGRID_API_KEY")
    if not sendgrid_key:
        print("⚠️  WARNING: SENDGRID_API_KEY not set in environment")
        print("The test will use current email configuration (likely Mailpit)")
        print("For true production test, set SENDGRID_API_KEY environment variable")
        print("="*60)
    
    # Create verifier
    verifier = LiveEmailVerification()
    
    print(f"Test email address: {verifier.test_email}")
    print(f"Security token: {verifier.security_token}")
    print("="*60)
    
    # Step 1: Send test email
    print("\n📧 STEP 1: Sending test email...")
    send_success = await verifier.send_test_email()
    
    if not send_success:
        print("❌ Failed to send test email. Aborting.")
        return False
    
    print("✅ Test email sent successfully")
    
    # Step 2: Wait and verify delivery
    print("\n⏳ STEP 2: Waiting for email delivery verification...")
    verification_success = await verifier.wait_and_verify()
    
    # Print summary
    verifier.print_summary()
    
    if verification_success:
        print("\n🎉 SUCCESS: Live email delivery verified!")
        print("Email successfully left our infrastructure and arrived at external mailbox.")
        return True
    else:
        print("\n❌ FAILURE: Email delivery not verified")
        print("Possible issues:")
        print("1. SendGrid not properly configured")
        print("2. Mail7.io API credentials incorrect")
        print("3. Email stuck in queue or blocked")
        print("4. Network/DNS issues")
        return False

if __name__ == "__main__":
    # Run async main
    success = asyncio.run(main())
    
    # Exit with appropriate code
    sys.exit(0 if success else 1)