# -*- coding: utf-8 -*-
"""
Management command to create a superuser for the accounts app.

Usage:
    python manage.py create_superuser --email admin@example.com --password admin123
    python manage.py create_superuser --interactive
"""

from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth import get_user_model
from django.db import transaction
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
import getpass
import sys

User = get_user_model()


class Command(BaseCommand):
    help = 'Create a superuser account'
    
    def add_arguments(self, parser):
        parser.add_argument(
            '--email',
            type=str,
            help='Email address for the superuser'
        )
        parser.add_argument(
            '--password',
            type=str,
            help='Password for the superuser'
        )
        parser.add_argument(
            '--first-name',
            type=str,
            help='First name for the superuser'
        )
        parser.add_argument(
            '--last-name',
            type=str,
            help='Last name for the superuser'
        )
        parser.add_argument(
            '--interactive',
            action='store_true',
            help='Prompt for user input interactively'
        )
        parser.add_argument(
            '--force',
            action='store_true',
            help='Force creation even if user exists'
        )
    
    def handle(self, *args, **options):
        email = options.get('email')
        password = options.get('password')
        first_name = options.get('first_name', '')
        last_name = options.get('last_name', '')
        interactive = options.get('interactive', False)
        force = options.get('force', False)
        
        # Interactive mode
        if interactive or not email or not password:
            self.stdout.write(self.style.SUCCESS('Creating superuser interactively...'))
            email, password, first_name, last_name = self._get_interactive_input(
                email, password, first_name, last_name
            )
        
        # Validate email
        try:
            validate_email(email)
        except ValidationError:
            raise CommandError(f'Invalid email address: {email}')
        
        # Check if user exists
        if User.objects.filter(email=email).exists():
            if not force:
                raise CommandError(
                    f'User with email {email} already exists. '
                    'Use --force to update existing user.'
                )
            else:
                self.stdout.write(
                    self.style.WARNING(f'Updating existing user: {email}')
                )
        
        # Create or update superuser
        try:
            with transaction.atomic():
                user, created = User.objects.get_or_create(
                    email=email,
                    defaults={
                        'first_name': first_name,
                        'last_name': last_name,
                        'is_staff': True,
                        'is_superuser': True,
                        'is_active': True,
                    }
                )
                
                if not created:
                    # Update existing user
                    user.first_name = first_name
                    user.last_name = last_name
                    user.is_staff = True
                    user.is_superuser = True
                    user.is_active = True
                
                user.set_password(password)
                user.save()
                
                action = 'created' if created else 'updated'
                self.stdout.write(
                    self.style.SUCCESS(
                        f'Successfully {action} superuser: {email}'
                    )
                )
                
                # Display user info
                self.stdout.write('\nUser details:')
                self.stdout.write(f'  Email: {user.email}')
                self.stdout.write(f'  Name: {user.get_full_name() or "Not provided"}')
                self.stdout.write(f'  Staff: {user.is_staff}')
                self.stdout.write(f'  Superuser: {user.is_superuser}')
                self.stdout.write(f'  Active: {user.is_active}')
                
        except Exception as e:
            raise CommandError(f'Error creating superuser: {str(e)}')
    
    def _get_interactive_input(self, email=None, password=None, first_name='', last_name=''):
        """Get user input interactively."""
        
        # Get email
        while not email:
            email = input('Email address: ').strip()
            if not email:
                self.stdout.write(self.style.ERROR('Email is required.'))
                continue
            
            try:
                validate_email(email)
                break
            except ValidationError:
                self.stdout.write(self.style.ERROR('Invalid email format.'))
                email = None
        
        # Get password
        while not password:
            password = getpass.getpass('Password: ')
            if not password:
                self.stdout.write(self.style.ERROR('Password is required.'))
                continue
            
            if len(password) < 8:
                self.stdout.write(
                    self.style.ERROR('Password must be at least 8 characters long.')
                )
                password = None
                continue
            
            # Confirm password
            password_confirm = getpass.getpass('Password (again): ')
            if password != password_confirm:
                self.stdout.write(self.style.ERROR('Passwords do not match.'))
                password = None
                continue
            
            break
        
        # Get optional fields
        if not first_name:
            first_name = input('First name (optional): ').strip()
        
        if not last_name:
            last_name = input('Last name (optional): ').strip()
        
        return email, password, first_name, last_name