"""
Django Management Command for Stream Processor Setup

This command helps set up the Stream Processor application by creating
default configurations, sample data, and validating the installation.
"""

from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import User
from django.conf import settings
from django.utils import timezone
from django.db import transaction
import os

# Import Django modules at the top level
# Models will be imported inside methods to avoid import issues 


class Command(BaseCommand):
    """
    Management command to set up the Stream Processor application.
    
    This command performs initial setup tasks including:
    - Creating default configurations
    - Setting up sample notification templates
    - Validating system requirements
    - Creating sample data for testing
    """
    
    help = 'Set up the Stream Processor application with default configurations'
    
    def add_arguments(self, parser):
        """
        Add command line arguments for the setup command.
        
        Args:
            parser: ArgumentParser instance for adding arguments
        """
        parser.add_argument(
            '--create-superuser',
            action='store_true',
            help='Create a superuser account'
        )
        
        parser.add_argument(
            '--admin-username',
            type=str,
            default='admin',
            help='Username for the admin account (default: admin)'
        )
        
        parser.add_argument(
            '--admin-email',
            type=str,
            default='admin@example.com',
            help='Email for the admin account'
        )
        
        parser.add_argument(
            '--create-sample-data',
            action='store_true',
            help='Create sample channels and configurations'
        )
        
        parser.add_argument(
            '--validate-only',
            action='store_true',
            help='Only validate the installation without making changes'
        )
    
    def handle(self, *args, **options):
        """
        Main command handler.
        
        Args:
            *args: Command arguments
            **options: Command options
        """
        self.stdout.write(
            self.style.SUCCESS('🚀 Setting up Stream Processor Application...\n')
        )
        
        try:
            # Validate system requirements
            self.validate_system()
            
            if options['validate_only']:
                self.stdout.write(
                    self.style.SUCCESS('✅ Validation completed successfully!')
                )
                return
            
            # Perform setup tasks
            with transaction.atomic():
                self.create_directories()
                self.create_default_configurations()
                self.create_notification_templates()
                
                if options['create_superuser']:
                    self.create_superuser(
                        username=options['admin_username'],
                        email=options['admin_email']
                    )
                
                if options['create_sample_data']:
                    self.create_sample_data()
            
            self.stdout.write(
                self.style.SUCCESS('\n🎉 Stream Processor setup completed successfully!')
            )
            self.display_next_steps()
            
        except Exception as e:
            raise CommandError(f'Setup failed: {str(e)}')
    
    def validate_system(self):
        """
        Validate system requirements and configuration.
        
        Raises:
            CommandError: If validation fails
        """
        self.stdout.write('🔍 Validating system requirements...')
        
        # Check Django database connection
        try:
            from django.db import connection
            with connection.cursor() as cursor:
                cursor.execute("SELECT 1")
            self.stdout.write('  ✅ Database connection: OK')
        except Exception as e:
            raise CommandError(f'Database connection failed: {e}')
        
        # Check Redis connection
        try:
            import redis
            r = redis.from_url(settings.CELERY_BROKER_URL)
            r.ping()
            self.stdout.write('  ✅ Redis connection: OK')
        except Exception as e:
            self.stdout.write(
                self.style.WARNING(f'  ⚠️  Redis connection failed: {e}')
            )
        
        # Check FFmpeg availability
        try:
            import subprocess
            result = subprocess.run(['ffmpeg', '-version'], 
                                  capture_output=True, timeout=10)
            if result.returncode == 0:
                self.stdout.write('  ✅ FFmpeg: Available')
            else:
                raise Exception('FFmpeg not working')
        except Exception as e:
            self.stdout.write(
                self.style.WARNING(f'  ⚠️  FFmpeg not available: {e}')
            )
        
        # Check OpenCV availability
        try:
            import cv2
            self.stdout.write(f'  ✅ OpenCV: Version {cv2.__version__}')
        except ImportError:
            self.stdout.write(
                self.style.WARNING('  ⚠️  OpenCV not available')
            )
        
        # Check required directories
        output_dir = settings.STREAM_CONFIG['OUTPUT_DIR']
        if os.path.exists(output_dir):
            self.stdout.write(f'  ✅ Output directory: {output_dir}')
        else:
            self.stdout.write(
                self.style.WARNING(f'  ⚠️  Output directory missing: {output_dir}')
            )
    
    def create_directories(self):
        """Create necessary directories for the application."""
        self.stdout.write('📁 Creating application directories...')
        
        directories = [
            settings.STREAM_CONFIG['OUTPUT_DIR'],
            os.path.join(settings.BASE_DIR, 'media', 'jingles'),
            os.path.join(settings.BASE_DIR, 'logs'),
            os.path.join(settings.BASE_DIR, 'media'),
            os.path.join(settings.BASE_DIR, 'static'),
        ]
        
        for directory in directories:
            try:
                os.makedirs(directory, exist_ok=True)
                self.stdout.write(f'  ✅ Created: {directory}')
            except Exception as e:
                self.stdout.write(
                    self.style.WARNING(f'  ⚠️  Failed to create {directory}: {e}')
                )
    
    def create_default_configurations(self):
        """Create default video and audio configurations."""
        from django.apps import apps
        VideoConfiguration = apps.get_model('streams', 'VideoConfiguration')
        AudioConfiguration = apps.get_model('streams', 'AudioConfiguration')
        
        self.stdout.write("⚙️  Creating default configurations...")
        
        # Video configurations
        video_configs = [
            {
                'name': 'HD 720p',
                'resolution': '1280x720',
                'aspect_ratio': '16:9',
                'frame_rate': 25,
                'min_bitrate': '2000k',
                'max_bitrate': '4000k',
                'codec': 'h264',
                'preset': 'medium',
                'profile': 'main',
                'level': '3.1'
            },
            {
                'name': 'SD 480p',
                'resolution': '854x480',
                'aspect_ratio': '16:9',
                'frame_rate': 25,
                'min_bitrate': '1000k',
                'max_bitrate': '2000k',
                'codec': 'h264',
                'preset': 'fast',
                'profile': 'main',
                'level': '3.0'
            }
        ]
        
        for config_data in video_configs:
            config, created = VideoConfiguration.objects.get_or_create(
                name=config_data['name'],
                defaults=config_data
            )
            if created:
                self.stdout.write(f'  ✅ Created video config: {config.name}')
        
        # Create default audio configurations
        audio_configs = [
            {
                'name': 'Standard AAC',
                'codec': 'aac',
                'bitrate': '128k',
                'sample_rate': 48000,
                'channels': 2,
                'normalize': True
            },
            {
                'name': 'High Quality AAC',
                'codec': 'aac',
                'bitrate': '256k',
                'sample_rate': 48000,
                'channels': 2,
                'normalize': True
            }
        ]
        
        for config_data in audio_configs:
            config, created = AudioConfiguration.objects.get_or_create(
                name=config_data['name'],
                defaults=config_data
            )
            if created:
                self.stdout.write(f'  ✅ Created audio config: {config.name}')
    
    def create_notification_templates(self):
        """Create default notification templates."""
        from django.apps import apps
        NotificationTemplate = apps.get_model('notifications', 'NotificationTemplate')
        
        self.stdout.write("📧 Creating notification templates...")
        
        templates = [
            {
                'name': 'Jingle Detection Alert',
                'template_type': 'jingle_detected',
                'subject_template': '🎵 Jingle Detected: {jingle_name}',
                'message_template': (
                    '🎵 <b>Jingle Detected</b> 🎵\n\n'
                    '<b>Name:</b> {jingle_name}\n'
                    '<b>Channel:</b> {channel_name}\n'
                    '<b>Confidence:</b> {confidence_score:.3f}\n'
                    '<b>Time:</b> {detection_time}'
                ),
                'variables': ['jingle_name', 'channel_name', 'confidence_score', 'detection_time'],
                'channel_types': ['telegram', 'email']
            },
            {
                'name': 'Ad Break Notification',
                'template_type': 'ad_break_ended',
                'subject_template': '🚨 Ad Break Detected: {channel_name}',
                'message_template': (
                    '🚨 <b>Ad Break Detected</b> 🚨\n\n'
                    '<b>Channel:</b> {channel_name}\n'
                    '<b>Region:</b> {region}\n'
                    '<b>Duration:</b> {duration_seconds} seconds\n'
                    '<b>Start:</b> {start_time}\n'
                    '<b>End:</b> {end_time}'
                ),
                'variables': ['channel_name', 'region', 'duration_seconds', 'start_time', 'end_time'],
                'channel_types': ['telegram', 'email', 'webhook']
            },
            {
                'name': 'Stream Status Alert',
                'template_type': 'stream_error',
                'subject_template': '⚠️ Stream Error: {channel_name}',
                'message_template': (
                    '⚠️ <b>Stream Error</b> ⚠️\n\n'
                    '<b>Channel:</b> {channel_name}\n'
                    '<b>Error:</b> {error_message}\n'
                    '<b>Time:</b> {timestamp}'
                ),
                'variables': ['channel_name', 'error_message', 'timestamp'],
                'channel_types': ['telegram', 'email']
            }
        ]
        
        for template_data in templates:
            template, created = NotificationTemplate.objects.get_or_create(
                name=template_data['name'],
                defaults=template_data
            )
            if created:
                self.stdout.write(f'  ✅ Created template: {template.name}')
    
    def create_superuser(self, username, email):
        """
        Create a superuser account.
        
        Args:
            username (str): Username for the superuser
            email (str): Email for the superuser
        """
        self.stdout.write(f'👤 Creating superuser account: {username}...')
        
        if User.objects.filter(username=username).exists():
            self.stdout.write(f'  ⚠️  User {username} already exists')
            return
        
        try:
            # Use a default password - user should change it immediately
            password = 'changeme123!'
            
            user = User.objects.create_superuser(
                username=username,
                email=email,
                password=password
            )
            
            self.stdout.write(f'  ✅ Created superuser: {username}')
            self.stdout.write(
                self.style.WARNING(
                    f'  🔑 Default password: {password} (CHANGE IMMEDIATELY!)'
                )
            )
            
        except Exception as e:
            self.stdout.write(
                self.style.ERROR(f'  ❌ Failed to create superuser: {e}')
            )
    
    def create_sample_data(self):
        """Create sample data for testing."""
        from django.apps import apps
        Channel = apps.get_model('streams', 'Channel')
        NotificationChannel = apps.get_model('notifications', 'NotificationChannel')
        NotificationRule = apps.get_model('notifications', 'NotificationRule')
        
        self.stdout.write('🧪 Creating sample data...')
        
        # Create sample channel
        admin_user = User.objects.filter(is_superuser=True).first()
        if not admin_user:
            self.stdout.write('  ⚠️  No admin user found, skipping sample data')
            return
        
        # Default 2M Monde channel
        channel_data = {
            'name': '2M Monde',
            'slug': '2m-monde',
            'hls_url': 'https://cdn-globecast.akamaized.net/live/eds/2m_monde/hls_video_ts_tuhawxpiemz257adfc/2m_monde-avc1_1500000=4-mp4a_130400_qad=1.m3u8',
            'description': '2M Monde - Moroccan television channel',
            'output_directory': settings.STREAM_CONFIG['OUTPUT_DIR'],
            'segment_duration': 6,
            'max_segments': 10,
            'retry_attempts': 3,
            'retry_interval': 30,
            'created_by': admin_user
        }
        
        channel, created = Channel.objects.get_or_create(
            slug='2m-monde',
            defaults=channel_data
        )
        if created:
            self.stdout.write(f'  ✅ Created default channel: {channel.name}')
        

        
        # Default notification channels
        from apps.notifications.models import NotificationChannel, NotificationRule, NotificationTemplate
        
        # Create default email notification channel
        email_channel_data = {
            'name': 'Default Email',
            'channel_type': 'email',
            'configuration': {
                'recipients': ['admin@streamprocessor.com'],
                'subject_prefix': '[Stream Processor]'
            },
            'rate_limit': 10,
            'retry_attempts': 3,
            'timeout_seconds': 30,
            'created_by': admin_user
        }
        
        email_channel, created = NotificationChannel.objects.get_or_create(
            name='Default Email',
            defaults=email_channel_data
        )
        if created:
            self.stdout.write('  ✅ Created default email notification channel')
        
        # Create Telegram notification channel if configured
        if hasattr(settings, 'TELEGRAM_CONFIG') and settings.TELEGRAM_CONFIG.get('BOT_TOKEN'):
            telegram_channel_data = {
                'name': 'Default Telegram',
                'channel_type': 'telegram',
                'configuration': {
                    'bot_token': settings.TELEGRAM_CONFIG['BOT_TOKEN'],
                    'chat_id': settings.TELEGRAM_CONFIG['CHAT_ID']
                },
                'rate_limit': 30,
                'retry_attempts': 3,
                'timeout_seconds': 30,
                'created_by': admin_user
            }
            
            telegram_channel, created = NotificationChannel.objects.get_or_create(
                name='Default Telegram',
                defaults=telegram_channel_data
            )
            if created:
                self.stdout.write('  ✅ Created default Telegram notification channel')
        
        # Create default notification rules
        default_channel = email_channel  # Use email as default
        
        # Get default templates
        jingle_template = NotificationTemplate.objects.filter(template_type='jingle_detected').first()
        stream_error_template = NotificationTemplate.objects.filter(template_type='stream_error').first()
        
        if jingle_template and stream_error_template:
            # Rule for jingle detection
            jingle_rule_data = {
                'name': 'Jingle Detection Alert',
                'event_type': 'jingle_detected',
                'channel': default_channel,
                'template': jingle_template,
                'is_active': True,
                'conditions': {
                    'min_confidence': 0.8,
                    'channels': ['2m-monde']  # Apply to our default channel
                },
                'throttle_minutes': 5,
                'priority': 1
            }
            
            jingle_rule, created = NotificationRule.objects.get_or_create(
                name='Jingle Detection Alert',
                defaults=jingle_rule_data
            )
            if created:
                self.stdout.write('  ✅ Created jingle detection notification rule')
            
            # Rule for stream errors
            error_rule_data = {
                'name': 'Stream Error Alert',
                'event_type': 'stream_error',
                'channel': default_channel,
                'template': stream_error_template,
                'is_active': True,
                'conditions': {
                    'channels': ['2m-monde']  # Apply to our default channel
                },
                'throttle_minutes': 10,
                'priority': 2
            }
            
            error_rule, created = NotificationRule.objects.get_or_create(
                name='Stream Error Alert',
                defaults=error_rule_data
            )
            if created:
                self.stdout.write('  ✅ Created stream error notification rule')
    
    def display_next_steps(self):
        """Display next steps for the user."""
        self.stdout.write('\n📋 Next Steps:')
        self.stdout.write('  1. 🔑 Change the default admin password if created')
        self.stdout.write('  2. ⚙️  Review configuration in the admin panel')
        self.stdout.write('  3. 🎵 Upload jingle templates for detection')
        self.stdout.write('  4. 📧 Configure notification channels')
        self.stdout.write('  5. 🎥 Create and start your first stream channel')
        self.stdout.write('')
        self.stdout.write('📚 Access Points:')
        self.stdout.write('  • Admin Panel: http://localhost:8000/admin/')
        self.stdout.write('  • API Docs: http://localhost:8000/api/v1/')
        self.stdout.write('  • Dashboard: http://localhost:8000/')
        self.stdout.write('')
        self.stdout.write('🔧 Management Commands:')
        self.stdout.write('  • python manage.py setup_stream_processor --help')
        self.stdout.write('  • python manage.py migrate')
        self.stdout.write('  • python manage.py collectstatic')
        self.stdout.write('')
        self.stdout.write('📖 Documentation: See README.md for detailed instructions')
