from django.core.management.base import BaseCommand
from django.contrib.sites.models import Site
from django.core.mail import send_mail, get_connection
from django.conf import settings
import requests
import json
import os
from email_service.models import EmailConfiguration
from email_service.services import EmailService
from email_service.backends import ForwardEmailBackend

class Command(BaseCommand):
    help = 'Test the email service functionality'

    def add_arguments(self, parser):
        parser.add_argument(
            '--to',
            type=str,
            help='Recipient email address (optional, defaults to current user\'s email)',
        )
        parser.add_argument(
            '--api-key',
            type=str,
            help='ForwardEmail API key (optional, will use configured value)',
        )
        parser.add_argument(
            '--from-email',
            type=str,
            help='Sender email address (optional, will use configured value)',
        )

    def get_config(self):
        """Get email configuration from database or environment"""
        try:
            site = Site.objects.get(id=settings.SITE_ID)
            config = EmailConfiguration.objects.get(site=site)
            return {
                'api_key': config.api_key,
                'from_email': config.default_from_email,
                'site': site
            }
        except (Site.DoesNotExist, EmailConfiguration.DoesNotExist):
            # Try environment variables
            api_key = os.environ.get('FORWARD_EMAIL_API_KEY')
            from_email = os.environ.get('FORWARD_EMAIL_FROM')
            
            if not api_key or not from_email:
                self.stdout.write(self.style.WARNING(
                    'No configuration found in database or environment variables.\n'
                    'Please either:\n'
                    '1. Configure email settings in Django admin, or\n'
                    '2. Set environment variables FORWARD_EMAIL_API_KEY and FORWARD_EMAIL_FROM, or\n'
                    '3. Provide --api-key and --from-email arguments'
                ))
                return None
            
            return {
                'api_key': api_key,
                'from_email': from_email,
                'site': Site.objects.get(id=settings.SITE_ID)
            }

    def handle(self, *args, **options):
        self.stdout.write(self.style.SUCCESS('Starting email service tests...'))

        # Get configuration
        config = self.get_config()
        if not config and not (options['api_key'] and options['from_email']):
            self.stdout.write(self.style.ERROR('No email configuration available. Tests aborted.'))
            return

        # Use provided values or fall back to config
        api_key = options['api_key'] or config['api_key']
        from_email = options['from_email'] or config['from_email']
        site = config['site']

        # If no recipient specified, use the from_email address for testing
        to_email = options['to'] or 'test@thrillwiki.com'

        self.stdout.write(self.style.SUCCESS(f'Using configuration:'))
        self.stdout.write(f'  From: {from_email}')
        self.stdout.write(f'  To: {to_email}')
        self.stdout.write(f'  API Key: {"*" * len(api_key)}')
        self.stdout.write(f'  Site: {site.domain}')

        try:
            # 1. Test site configuration
            config = self.test_site_configuration(api_key, from_email)
            
            # 2. Test direct service
            self.test_email_service_directly(to_email, config.site)

            # 3. Test API endpoint
            self.test_api_endpoint(to_email)

            # 4. Test Django email backend
            self.test_email_backend(to_email, config.site)

            self.stdout.write(self.style.SUCCESS('\nAll tests completed successfully! 🎉'))
            
        except Exception as e:
            self.stdout.write(self.style.ERROR(f'\nTests failed: {str(e)}'))

    def test_site_configuration(self, api_key, from_email):
        """Test creating and retrieving site configuration"""
        self.stdout.write('\nTesting site configuration...')
        
        try:
            # Get or create default site
            site = Site.objects.get_or_create(
                id=settings.SITE_ID,
                defaults={
                    'domain': 'example.com',
                    'name': 'example.com'
                }
            )[0]

            # Create or update email configuration
            config, created = EmailConfiguration.objects.update_or_create(
                site=site,
                defaults={
                    'api_key': api_key,
                    'default_from_email': from_email
                }
            )

            action = 'Created new' if created else 'Updated existing'
            self.stdout.write(self.style.SUCCESS(f'✓ {action} site configuration'))
            return config
        except Exception as e:
            self.stdout.write(self.style.ERROR(f'✗ Site configuration failed: {str(e)}'))
            raise

    def test_api_endpoint(self, to_email):
        """Test sending email via the API endpoint"""
        self.stdout.write('\nTesting API endpoint...')
        
        try:
            # Make request to the API endpoint
            response = requests.post(
                'http://127.0.0.1:8000/api/email/send-email/',
                json={
                    'to': to_email,
                    'subject': 'Test Email via API',
                    'text': 'This is a test email sent via the API endpoint.'
                },
                headers={
                    'Content-Type': 'application/json',
                }
            )

            if response.status_code == 200:
                self.stdout.write(self.style.SUCCESS('✓ API endpoint test successful'))
            else:
                self.stdout.write(
                    self.style.ERROR(
                        f'✗ API endpoint test failed with status {response.status_code}: {response.text}'
                    )
                )
                raise Exception(f"API test failed: {response.text}")
        except requests.exceptions.ConnectionError:
            self.stdout.write(
                self.style.ERROR(
                    '✗ API endpoint test failed: Could not connect to server. '
                    'Make sure the Django development server is running.'
                )
            )
            raise Exception("Could not connect to Django server")
        except Exception as e:
            self.stdout.write(self.style.ERROR(f'✗ API endpoint test failed: {str(e)}'))
            raise

    def test_email_backend(self, to_email, site):
        """Test sending email via Django's email backend"""
        self.stdout.write('\nTesting Django email backend...')
        
        try:
            # Create a connection with site context
            backend = ForwardEmailBackend(fail_silently=False, site=site)
            
            # Debug output
            self.stdout.write(f'  Debug: Using from_email: {site.email_config.default_from_email}')
            self.stdout.write(f'  Debug: Using to_email: {to_email}')
            
            send_mail(
                subject='Test Email via Backend',
                message='This is a test email sent via the Django email backend.',
                from_email=site.email_config.default_from_email,  # Explicitly set from_email
                recipient_list=[to_email],
                fail_silently=False,
                connection=backend
            )
            self.stdout.write(self.style.SUCCESS('✓ Email backend test successful'))
        except Exception as e:
            self.stdout.write(self.style.ERROR(f'✗ Email backend test failed: {str(e)}'))
            raise

    def test_email_service_directly(self, to_email, site):
        """Test sending email directly via EmailService"""
        self.stdout.write('\nTesting EmailService directly...')
        
        try:
            response = EmailService.send_email(
                to=to_email,
                subject='Test Email via Service',
                text='This is a test email sent directly via the EmailService.',
                site=site
            )
            self.stdout.write(self.style.SUCCESS('✓ Direct EmailService test successful'))
            return response
        except Exception as e:
            self.stdout.write(self.style.ERROR(f'✗ Direct EmailService test failed: {str(e)}'))
            raise
