from django.core.management.base import BaseCommand
from django.contrib.auth import get_user_model
from django.contrib.sites.models import Site
from django.test import RequestFactory, Client
from allauth.account.models import EmailAddress
from accounts.adapters import CustomAccountAdapter
from email_service.services import EmailService
from django.conf import settings
import uuid

User = get_user_model()

class Command(BaseCommand):
    help = 'Test all email flows in the application'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.factory = RequestFactory()
        self.client = Client(enforce_csrf_checks=False)  # Disable CSRF for testing
        self.adapter = CustomAccountAdapter()
        self.site = Site.objects.get_current()
        
        # Generate unique test data
        unique_id = str(uuid.uuid4())[:8]
        self.test_username = f'testuser_{unique_id}'
        self.test_email = f'test_{unique_id}@thrillwiki.com'
        self.test_[PASSWORD-REMOVED]"
        self.new_[PASSWORD-REMOVED]"

        # Add testserver to ALLOWED_HOSTS
        if 'testserver' not in settings.ALLOWED_HOSTS:
            settings.ALLOWED_HOSTS.append('testserver')

    def handle(self, *args, **options):
        self.stdout.write('Starting email flow tests...\n')

        # Clean up any existing test users
        User.objects.filter(email__endswith='@thrillwiki.com').delete()

        # Test registration email
        self.test_registration()

        # Create a test user for other flows
        user = User.objects.create_user(
            username=f'testuser2_{str(uuid.uuid4())[:8]}',
            email=f'test2_{str(uuid.uuid4())[:8]}@thrillwiki.com',
            password=self.test_password
        )
        EmailAddress.objects.create(
            user=user,
            email=user.email,
            primary=True,
            verified=True
        )

        # Log in the test user
        self.client.force_login(user)

        # Test other flows
        self.test_password_change(user)
        self.test_email_change(user)
        self.test_password_reset(user)

        # Cleanup
        User.objects.filter(email__endswith='@thrillwiki.com').delete()
        self.stdout.write(self.style.SUCCESS('All email flow tests completed!\n'))

    def test_registration(self):
        """Test registration email flow"""
        self.stdout.write('Testing registration email...')
        try:
            # Use dj-rest-auth registration endpoint
            response = self.client.post('/api/auth/registration/', {
                'username': self.test_username,
                'email': self.test_email,
                'password1': self.test_password,
                'password2': self.test_password
            }, content_type='application/json')
            
            if response.status_code in [200, 201, 204]:
                self.stdout.write(self.style.SUCCESS('Registration email test passed!\n'))
            else:
                self.stdout.write(
                    self.style.WARNING(
                        f'Registration returned status {response.status_code}: {response.content.decode()}\n'
                    )
                )
        except Exception as e:
            self.stdout.write(self.style.ERROR(f'Registration email test failed: {str(e)}\n'))

    def test_password_change(self, user):
        """Test password change using dj-rest-auth"""
        self.stdout.write('Testing password change email...')
        try:
            response = self.client.post('/api/auth/password/change/', {
                'old_password': self.test_password,
                'new_password1': self.new_password,
                'new_password2': self.new_password
            }, content_type='application/json')
            
            if response.status_code == 200:
                self.stdout.write(self.style.SUCCESS('Password change email test passed!\n'))
            else:
                self.stdout.write(
                    self.style.WARNING(
                        f'Password change returned status {response.status_code}: {response.content.decode()}\n'
                    )
                )
        except Exception as e:
            self.stdout.write(self.style.ERROR(f'Password change email test failed: {str(e)}\n'))

    def test_email_change(self, user):
        """Test email change verification"""
        self.stdout.write('Testing email change verification...')
        try:
            new_email = f'newemail_{str(uuid.uuid4())[:8]}@thrillwiki.com'
            response = self.client.post('/api/auth/email/', {
                'email': new_email
            }, content_type='application/json')
            
            if response.status_code == 200:
                self.stdout.write(self.style.SUCCESS('Email change verification test passed!\n'))
            else:
                self.stdout.write(
                    self.style.WARNING(
                        f'Email change returned status {response.status_code}: {response.content.decode()}\n'
                    )
                )
        except Exception as e:
            self.stdout.write(self.style.ERROR(f'Email change verification test failed: {str(e)}\n'))

    def test_password_reset(self, user):
        """Test password reset using dj-rest-auth"""
        self.stdout.write('Testing password reset email...')
        try:
            # Request password reset
            response = self.client.post('/api/auth/password/reset/', {
                'email': user.email
            }, content_type='application/json')
            
            if response.status_code == 200:
                self.stdout.write(self.style.SUCCESS('Password reset email test passed!\n'))
            else:
                self.stdout.write(
                    self.style.WARNING(
                        f'Password reset returned status {response.status_code}: {response.content.decode()}\n'
                    )
                )
        except Exception as e:
            self.stdout.write(self.style.ERROR(f'Password reset email test failed: {str(e)}\n'))
