"""
CODH Core Serializers
"""

import re
import subprocess
import platform
import os
from django.core.validators import URLValidator
from rest_framework import serializers
from cryptography.fernet import Fernet
from .models import SystemConfiguration, SetupWizardProgress, AuditLog, BackgroundTask


class ServerRequirementsSerializer(serializers.Serializer):
    """Check server requirements"""
    
    python_version = serializers.CharField(read_only=True)
    python_ok = serializers.BooleanField(read_only=True)
    php_version = serializers.CharField(read_only=True)
    php_ok = serializers.BooleanField(read_only=True)
    mysql_version = serializers.CharField(read_only=True)
    mysql_ok = serializers.BooleanField(read_only=True)
    redis_available = serializers.BooleanField(read_only=True)
    disk_space_gb = serializers.FloatField(read_only=True)
    disk_ok = serializers.BooleanField(read_only=True)
    memory_gb = serializers.FloatField(read_only=True)
    all_requirements_met = serializers.BooleanField(read_only=True)
    
    def check_requirements(self):
        """Check all server requirements"""
        data = {}
        
        # Check Python version
        import sys
        py_version = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
        py_ok = sys.version_info >= (3, 11)
        data['python_version'] = py_version
        data['python_ok'] = py_ok
        
        # Check PHP version
        try:
            result = subprocess.run(['php', '-v'], capture_output=True, text=True, timeout=5)
            php_match = re.search(r'PHP (\d+\.\d+\.\d+)', result.stdout)
            if php_match:
                php_version = php_match.group(1)
                php_major, php_minor, _ = php_version.split('.')
                php_ok = int(php_major) >= 8
            else:
                php_version = 'Not detected'
                php_ok = False
        except:
            php_version = 'Not installed'
            php_ok = False
        
        data['php_version'] = php_version
        data['php_ok'] = php_ok
        
        # Check MySQL version
        try:
            import mysql.connector
            conn = mysql.connector.connect(
                host=os.getenv('DB_HOST', 'localhost'),
                user=os.getenv('DB_USER', ''),
                password=os.getenv('DB_PASSWORD', ''),
            )
            cursor = conn.cursor()
            cursor.execute("SELECT VERSION()")
            mysql_version = cursor.fetchone()[0]
            conn.close()
            mysql_ok = True
        except:
            mysql_version = 'Not connected'
            mysql_ok = False
        
        data['mysql_version'] = mysql_version
        data['mysql_ok'] = mysql_ok
        
        # Check Redis
        try:
            import redis
            r = redis.from_url(os.getenv('REDIS_URL', 'redis://localhost:6379/0'))
            r.ping()
            redis_available = True
        except:
            redis_available = False
        
        data['redis_available'] = redis_available
        
        # Check disk space
        try:
            import shutil
            total, used, free = shutil.disk_usage("/")
            disk_gb = free / (1024**3)
            disk_ok = disk_gb >= 5  # Require at least 5GB free
        except:
            disk_gb = 0
            disk_ok = False
        
        data['disk_space_gb'] = round(disk_gb, 2)
        data['disk_ok'] = disk_ok
        
        # Check memory
        try:
            import psutil
            mem = psutil.virtual_memory()
            memory_gb = mem.total / (1024**3)
        except:
            memory_gb = 0
        
        data['memory_gb'] = round(memory_gb, 2)
        
        # Overall status
        data['all_requirements_met'] = all([
            py_ok, php_ok, mysql_ok, redis_available, disk_ok
        ])
        
        return data


class DatabaseConfigSerializer(serializers.Serializer):
    """Database configuration serializer"""
    
    db_host = serializers.CharField(default='localhost')
    db_port = serializers.IntegerField(default=3306)
    db_name = serializers.CharField()
    db_user = serializers.CharField()
    db_password = serializers.CharField(write_only=True)
    create_database = serializers.BooleanField(default=True)
    
    def validate(self, data):
        """Test database connection"""
        try:
            import mysql.connector
            conn = mysql.connector.connect(
                host=data['db_host'],
                port=data['db_port'],
                user=data['db_user'],
                password=data['db_password'],
            )
            
            if data.get('create_database'):
                cursor = conn.cursor()
                cursor.execute(f"CREATE DATABASE IF NOT EXISTS {data['db_name']} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci")
                conn.commit()
            
            conn.close()
        except Exception as e:
            raise serializers.ValidationError(f"Database connection failed: {str(e)}")
        
        return data


class AdminAccountSerializer(serializers.Serializer):
    """Super admin account creation serializer"""
    
    email = serializers.EmailField()
    password = serializers.CharField(min_length=12, write_only=True)
    password_confirm = serializers.CharField(write_only=True)
    first_name = serializers.CharField(max_length=150)
    last_name = serializers.CharField(max_length=150)
    company_name = serializers.CharField(max_length=255, required=False)
    
    def validate(self, data):
        if data['password'] != data['password_confirm']:
            raise serializers.ValidationError("Passwords do not match")
        return data


class APIConfigSerializer(serializers.Serializer):
    """API configuration serializer"""
    
    # KIMI AI
    kimi_api_key = serializers.CharField(required=False, allow_blank=True)
    
    # MOFH
    mofh_api_key = serializers.CharField(required=False, allow_blank=True)
    mofh_api_username = serializers.CharField(required=False, allow_blank=True)
    mofh_api_password = serializers.CharField(required=False, allow_blank=True, write_only=True)
    
    # VPS.TC
    vpstc_api_key = serializers.CharField(required=False, allow_blank=True)
    
    def encrypt_value(self, value):
        """Encrypt API key value"""
        if not value:
            return None
        key = Fernet.generate_key()
        f = Fernet(key)
        return f.encrypt(value.encode())


class PaymentConfigSerializer(serializers.Serializer):
    """Payment gateway configuration serializer"""
    
    # Paystack
    paystack_secret_key = serializers.CharField(required=False, allow_blank=True)
    paystack_public_key = serializers.CharField(required=False, allow_blank=True)
    paystack_enabled = serializers.BooleanField(default=False)
    
    # Flutterwave
    flutterwave_secret_key = serializers.CharField(required=False, allow_blank=True)
    flutterwave_public_key = serializers.CharField(required=False, allow_blank=True)
    flutterwave_enabled = serializers.BooleanField(default=False)
    
    # Stripe
    stripe_secret_key = serializers.CharField(required=False, allow_blank=True)
    stripe_public_key = serializers.CharField(required=False, allow_blank=True)
    stripe_enabled = serializers.BooleanField(default=False)
    
    # Currency
    default_currency = serializers.ChoiceField(choices=[
        ('USD', 'US Dollar'),
        ('EUR', 'Euro'),
        ('GBP', 'British Pound'),
        ('NGN', 'Nigerian Naira'),
    ], default='USD')


class BrandingConfigSerializer(serializers.Serializer):
    """Branding configuration serializer"""
    
    platform_name = serializers.CharField(max_length=255)
    platform_url = serializers.URLField()
    company_name = serializers.CharField(max_length=255)
    primary_color = serializers.RegexField(r'^#[0-9A-Fa-f]{6}$', default='#4ADE80')
    secondary_color = serializers.RegexField(r'^#[0-9A-Fa-f]{6}$', default='#60A5FA')
    accent_color = serializers.RegexField(r'^#[0-9A-Fa-f]{6}$', default='#FB923C')
    default_timezone = serializers.CharField(default='UTC')


class SetupCompleteSerializer(serializers.Serializer):
    """Finalize setup serializer"""
    
    confirm = serializers.BooleanField()
    
    def validate_confirm(self, value):
        if not value:
            raise serializers.ValidationError("You must confirm to complete setup")
        return value


class SystemConfigurationSerializer(serializers.ModelSerializer):
    """System configuration serializer"""
    
    class Meta:
        model = SystemConfiguration
        fields = [
            'id', 'is_configured', 'platform_name', 'platform_url',
            'company_name', 'security_team', 'primary_color',
            'secondary_color', 'accent_color', 'default_currency',
            'default_timezone', 'maintenance_mode', 'created_at', 'updated_at'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']


class AuditLogSerializer(serializers.ModelSerializer):
    """Audit log serializer"""
    
    user_email = serializers.CharField(source='user.email', read_only=True)
    
    class Meta:
        model = AuditLog
        fields = [
            'id', 'user', 'user_email', 'action', 'description',
            'ip_address', 'response_status', 'severity',
            'created_at'
        ]


class BackgroundTaskSerializer(serializers.ModelSerializer):
    """Background task serializer"""
    
    duration_seconds = serializers.SerializerMethodField()
    
    class Meta:
        model = BackgroundTask
        fields = [
            'id', 'task_type', 'task_name', 'status',
            'progress_percent', 'current_step', 'error_message',
            'retry_count', 'started_at', 'completed_at',
            'created_at', 'duration_seconds'
        ]
    
    def get_duration_seconds(self, obj):
        if obj.started_at and obj.completed_at:
            return (obj.completed_at - obj.started_at).total_seconds()
        return None
