"""
CODH Core Views
Setup Wizard and System Management
"""

import os
from datetime import datetime
from django.conf import settings
from django.db import connection
from django.contrib.auth import get_user_model
from rest_framework import status, generics, permissions
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from rest_framework.views import APIView
from cryptography.fernet import Fernet

from .models import SystemConfiguration, SetupWizardProgress, BackgroundTask, SystemHealth
from .serializers import (
    ServerRequirementsSerializer, DatabaseConfigSerializer,
    AdminAccountSerializer, APIConfigSerializer, PaymentConfigSerializer,
    BrandingConfigSerializer, SetupCompleteSerializer,
    SystemConfigurationSerializer, AuditLogSerializer, BackgroundTaskSerializer
)
from .tasks import test_celery_task, run_health_check

User = get_user_model()


class SetupWizardStatusView(APIView):
    """Get current setup wizard status"""
    permission_classes = [permissions.AllowAny]
    
    def get(self, request):
        try:
            progress = SetupWizardProgress.objects.first()
            if not progress:
                progress = SetupWizardProgress.objects.create()
            
            return Response({
                'installation_mode': settings.INSTALLATION_MODE,
                'current_step': progress.current_step,
                'is_completed': progress.is_completed,
                'requirements_met': {
                    'python': progress.python_version_ok,
                    'php': progress.php_version_ok,
                    'mysql': progress.mysql_version_ok,
                    'redis': progress.redis_ok,
                    'disk': progress.disk_space_ok,
                }
            })
        except Exception as e:
            return Response({
                'installation_mode': settings.INSTALLATION_MODE,
                'current_step': 'requirements',
                'is_completed': False,
                'error': str(e)
            })


class CheckServerRequirementsView(APIView):
    """Check server requirements"""
    permission_classes = [permissions.AllowAny]
    
    def get(self, request):
        serializer = ServerRequirementsSerializer()
        data = serializer.check_requirements()
        
        # Update progress
        progress, _ = SetupWizardProgress.objects.get_or_create(pk=1)
        progress.python_version_ok = data['python_ok']
        progress.php_version_ok = data['php_ok']
        progress.mysql_version_ok = data['mysql_ok']
        progress.redis_ok = data['redis_available']
        progress.disk_space_ok = data['disk_ok']
        progress.save()
        
        return Response(data)


class ConfigureDatabaseView(APIView):
    """Configure database connection"""
    permission_classes = [permissions.AllowAny]
    
    def post(self, request):
        serializer = DatabaseConfigSerializer(data=request.data)
        if serializer.is_valid():
            # Save to environment
            data = serializer.validated_data
            
            # Update .env file
            env_path = os.path.join(settings.BASE_DIR, '.env')
            env_vars = {
                'DB_HOST': data['db_host'],
                'DB_PORT': str(data['db_port']),
                'DB_NAME': data['db_name'],
                'DB_USER': data['db_user'],
                'DB_PASSWORD': data['db_password'],
            }
            
            # Write to .env
            with open(env_path, 'a') as f:
                for key, value in env_vars.items():
                    f.write(f"\n{key}={value}")
            
            # Run migrations
            try:
                from django.core.management import call_command
                call_command('migrate', '--noinput')
                
                # Update progress
                progress, _ = SetupWizardProgress.objects.get_or_create(pk=1)
                progress.current_step = 'admin'
                progress.save()
                
                return Response({
                    'status': 'success',
                    'message': 'Database configured and migrations applied',
                    'next_step': 'admin'
                })
            except Exception as e:
                return Response({
                    'status': 'error',
                    'message': f'Migration failed: {str(e)}'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class CreateAdminAccountView(APIView):
    """Create super admin account"""
    permission_classes = [permissions.AllowAny]
    
    def post(self, request):
        serializer = AdminAccountSerializer(data=request.data)
        if serializer.is_valid():
            data = serializer.validated_data
            
            # Create superuser
            user = User.objects.create_superuser(
                email=data['email'],
                password=data['password'],
                first_name=data['first_name'],
                last_name=data['last_name'],
                company_name=data.get('company_name', ''),
                role='super_admin'
            )
            
            # Update progress
            progress, _ = SetupWizardProgress.objects.get_or_create(pk=1)
            progress.current_step = 'api'
            progress.save()
            
            return Response({
                'status': 'success',
                'message': 'Admin account created successfully',
                'user_id': str(user.id),
                'next_step': 'api'
            })
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ConfigureAPIView(APIView):
    """Configure API integrations"""
    permission_classes = [permissions.AllowAny]
    
    def post(self, request):
        serializer = APIConfigSerializer(data=request.data)
        if serializer.is_valid():
            data = serializer.validated_data
            
            # Generate encryption key
            encryption_key = Fernet.generate_key()
            
            # Update .env file
            env_path = os.path.join(settings.BASE_DIR, '.env')
            env_vars = {
                'KIMI_API_KEY': data.get('kimi_api_key', ''),
                'MOFH_API_KEY': data.get('mofh_api_key', ''),
                'MOFH_API_USERNAME': data.get('mofh_api_username', ''),
                'MOFH_API_PASSWORD': data.get('mofh_api_password', ''),
                'VPSTC_API_KEY': data.get('vpstc_api_key', ''),
                'ENCRYPTION_KEY': encryption_key.decode(),
            }
            
            with open(env_path, 'a') as f:
                for key, value in env_vars.items():
                    if value:
                        f.write(f"\n{key}={value}")
            
            # Update progress
            progress, _ = SetupWizardProgress.objects.get_or_create(pk=1)
            progress.current_step = 'payment'
            progress.save()
            
            return Response({
                'status': 'success',
                'message': 'API configuration saved',
                'next_step': 'payment'
            })
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ConfigurePaymentView(APIView):
    """Configure payment gateways"""
    permission_classes = [permissions.AllowAny]
    
    def post(self, request):
        serializer = PaymentConfigSerializer(data=request.data)
        if serializer.is_valid():
            data = serializer.validated_data
            
            # Update .env file
            env_path = os.path.join(settings.BASE_DIR, '.env')
            env_vars = {
                'PAYSTACK_SECRET_KEY': data.get('paystack_secret_key', ''),
                'PAYSTACK_PUBLIC_KEY': data.get('paystack_public_key', ''),
                'PAYSTACK_ENABLED': str(data.get('paystack_enabled', False)),
                'FLUTTERWAVE_SECRET_KEY': data.get('flutterwave_secret_key', ''),
                'FLUTTERWAVE_PUBLIC_KEY': data.get('flutterwave_public_key', ''),
                'FLUTTERWAVE_ENABLED': str(data.get('flutterwave_enabled', False)),
                'STRIPE_SECRET_KEY': data.get('stripe_secret_key', ''),
                'STRIPE_PUBLIC_KEY': data.get('stripe_public_key', ''),
                'STRIPE_ENABLED': str(data.get('stripe_enabled', False)),
                'PLATFORM_CURRENCY': data.get('default_currency', 'USD'),
            }
            
            with open(env_path, 'a') as f:
                for key, value in env_vars.items():
                    f.write(f"\n{key}={value}")
            
            # Update progress
            progress, _ = SetupWizardProgress.objects.get_or_create(pk=1)
            progress.current_step = 'branding'
            progress.save()
            
            return Response({
                'status': 'success',
                'message': 'Payment configuration saved',
                'next_step': 'branding'
            })
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ConfigureBrandingView(APIView):
    """Configure branding and final settings"""
    permission_classes = [permissions.AllowAny]
    
    def post(self, request):
        serializer = BrandingConfigSerializer(data=request.data)
        if serializer.is_valid():
            data = serializer.validated_data
            
            # Update .env file
            env_path = os.path.join(settings.BASE_DIR, '.env')
            env_vars = {
                'PLATFORM_NAME': data['platform_name'],
                'PLATFORM_URL': data['platform_url'],
                'COMPANY_NAME': data['company_name'],
                'PRIMARY_COLOR': data['primary_color'],
                'SECONDARY_COLOR': data['secondary_color'],
                'ACCENT_COLOR': data['accent_color'],
                'PLATFORM_TIMEZONE': data['default_timezone'],
            }
            
            with open(env_path, 'a') as f:
                for key, value in env_vars.items():
                    f.write(f"\n{key}={value}")
            
            # Create system configuration
            config, _ = SystemConfiguration.objects.get_or_create(pk=1)
            config.platform_name = data['platform_name']
            config.platform_url = data['platform_url']
            config.company_name = data['company_name']
            config.primary_color = data['primary_color']
            config.secondary_color = data['secondary_color']
            config.accent_color = data['accent_color']
            config.default_timezone = data['default_timezone']
            config.save()
            
            # Update progress
            progress, _ = SetupWizardProgress.objects.get_or_create(pk=1)
            progress.current_step = 'complete'
            progress.save()
            
            return Response({
                'status': 'success',
                'message': 'Branding configuration saved',
                'next_step': 'complete'
            })
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class CompleteSetupView(APIView):
    """Finalize system setup"""
    permission_classes = [permissions.AllowAny]
    
    def post(self, request):
        serializer = SetupCompleteSerializer(data=request.data)
        if serializer.is_valid():
            # Mark setup as complete
            progress, _ = SetupWizardProgress.objects.get_or_create(pk=1)
            progress.is_completed = True
            progress.completed_at = datetime.now()
            progress.save()
            
            # Update system configuration
            config, _ = SystemConfiguration.objects.get_or_create(pk=1)
            config.is_configured = True
            config.installation_date = datetime.now()
            config.save()
            
            # Update .env to disable installation mode
            env_path = os.path.join(settings.BASE_DIR, '.env')
            with open(env_path, 'a') as f:
                f.write(f"\nINSTALLATION_MODE=False")
            
            # Initialize background tasks
            test_celery_task.delay()
            
            return Response({
                'status': 'success',
                'message': 'Setup completed successfully',
                'redirect': '/admin/dashboard'
            })
        
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class SystemConfigView(generics.RetrieveUpdateAPIView):
    """Get/Update system configuration"""
    queryset = SystemConfiguration.objects.all()
    serializer_class = SystemConfigurationSerializer
    permission_classes = [permissions.IsAdminUser]
    
    def get_object(self):
        return SystemConfiguration.get_config()


class AuditLogListView(generics.ListAPIView):
    """List audit logs"""
    queryset = AuditLog.objects.all()
    serializer_class = AuditLogSerializer
    permission_classes = [permissions.IsAdminUser]
    
    def get_queryset(self):
        queryset = AuditLog.objects.all()
        
        # Filter by user
        user_id = self.request.query_params.get('user')
        if user_id:
            queryset = queryset.filter(user_id=user_id)
        
        # Filter by severity
        severity = self.request.query_params.get('severity')
        if severity:
            queryset = queryset.filter(severity=severity)
        
        # Filter by date range
        date_from = self.request.query_params.get('date_from')
        date_to = self.request.query_params.get('date_to')
        if date_from:
            queryset = queryset.filter(created_at__gte=date_from)
        if date_to:
            queryset = queryset.filter(created_at__lte=date_to)
        
        return queryset[:1000]  # Limit results


class BackgroundTaskListView(generics.ListAPIView):
    """List background tasks"""
    queryset = BackgroundTask.objects.all()
    serializer_class = BackgroundTaskSerializer
    permission_classes = [permissions.IsAdminUser]
    
    def get_queryset(self):
        queryset = BackgroundTask.objects.all()
        
        # Filter by status
        status_filter = self.request.query_params.get('status')
        if status_filter:
            queryset = queryset.filter(status=status_filter)
        
        # Filter by type
        task_type = self.request.query_params.get('type')
        if task_type:
            queryset = queryset.filter(task_type=task_type)
        
        return queryset[:500]


class BackgroundTaskDetailView(generics.RetrieveAPIView):
    """Get background task details"""
    queryset = BackgroundTask.objects.all()
    serializer_class = BackgroundTaskSerializer
    permission_classes = [permissions.IsAdminUser]


@api_view(['POST'])
@permission_classes([permissions.IsAdminUser])
def retry_task(request, task_id):
    """Retry a failed background task"""
    try:
        task = BackgroundTask.objects.get(id=task_id)
        if task.status == 'failed':
            task.status = 'pending'
            task.retry_count += 1
            task.save()
            
            # Re-queue task based on type
            from .tasks import TASK_MAPPING
            if task.task_type in TASK_MAPPING:
                TASK_MAPPING[task.task_type].delay(task.id)
            
            return Response({'status': 'success', 'message': 'Task requeued'})
        return Response({'status': 'error', 'message': 'Task cannot be retried'}, status=400)
    except BackgroundTask.DoesNotExist:
        return Response({'status': 'error', 'message': 'Task not found'}, status=404)


@api_view(['GET'])
@permission_classes([permissions.AllowAny])
def health_check(request):
    """System health check endpoint"""
    try:
        # Check database
        with connection.cursor() as cursor:
            cursor.execute("SELECT 1")
            db_ok = cursor.fetchone() is not None
    except:
        db_ok = False
    
    # Check Redis
    try:
        import redis
        r = redis.from_url(settings.CACHES['default']['LOCATION'])
        r.ping()
        redis_ok = True
    except:
        redis_ok = False
    
    # Check Celery
    try:
        from .celery import app
        inspector = app.control.inspect()
        celery_ok = inspector.ping() is not None
    except:
        celery_ok = False
    
    overall_status = 'healthy' if all([db_ok, redis_ok]) else 'unhealthy'
    
    return Response({
        'status': overall_status,
        'timestamp': datetime.now().isoformat(),
        'version': settings.PLATFORM_VERSION,
        'checks': {
            'database': 'ok' if db_ok else 'error',
            'redis': 'ok' if redis_ok else 'error',
            'celery': 'ok' if celery_ok else 'warning',
        }
    }, status=200 if overall_status == 'healthy' else 503)


@api_view(['GET'])
@permission_classes([permissions.IsAdminUser])
def system_stats(request):
    """Get system statistics"""
    from apps.users.models import User
    from apps.projects.models import Project
    from apps.hosting.models import HostingAccount
    from apps.subscriptions.models import Subscription
    from apps.payments.models import Payment
    
    return Response({
        'users': {
            'total': User.objects.count(),
            'active': User.objects.filter(is_active=True).count(),
            'new_today': User.objects.filter(date_joined__date=datetime.now().date()).count(),
        },
        'projects': {
            'total': Project.objects.count(),
            'active': Project.objects.filter(status='active').count(),
        },
        'hosting': {
            'total_accounts': HostingAccount.objects.count(),
            'active': HostingAccount.objects.filter(status='active').count(),
        },
        'subscriptions': {
            'total': Subscription.objects.count(),
            'active': Subscription.objects.filter(status='active').count(),
            'expired': Subscription.objects.filter(status='expired').count(),
        },
        'revenue': {
            'today': Payment.get_today_revenue(),
            'this_month': Payment.get_month_revenue(),
            'this_year': Payment.get_year_revenue(),
        },
        'tasks': {
            'pending': BackgroundTask.objects.filter(status='pending').count(),
            'running': BackgroundTask.objects.filter(status='running').count(),
            'failed': BackgroundTask.objects.filter(status='failed').count(),
        }
    })
