from rest_framework import serializers
from .models import Configuration, ConfigurationTranslation, AppSettings

class ConfigurationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Configuration
        fields = ['header', 'icon', 'color', 'questions', 'is_quick_menu', 'visibility_rule']

class FunctionConfigSerializer(serializers.Serializer):
    header = serializers.CharField(max_length=255)
    icon = serializers.CharField(max_length=100)
    color = serializers.CharField(max_length=50)
    questions = serializers.ListField(child=serializers.CharField(), required=False, default=list)

class MenuSerializer(serializers.Serializer):
    def to_internal_value(self, data):
        if not isinstance(data, dict):
            raise serializers.ValidationError("Data must be a dictionary")
            
        result = {}
        for key, value in data.items():
            if key in ['InMenu', 'OutMenu']:
                if not isinstance(value, dict):
                    raise serializers.ValidationError(f"{key} value must be a dictionary")
                    
                for function_id, config in value.items():
                    if not isinstance(config, dict):
                        raise serializers.ValidationError(f"Configuration for {function_id} must be a dictionary")
                        
                    result = {
                        'header': config.get('header', ''),
                        'icon': config.get('icon', ''),
                        'color': config.get('color', ''),
                        'questions': config.get('questions', []),
                        'function_ref_id': function_id,
                        'menu_type': key,
                        'is_quick_menu': config.get('is_quick_menu', False),
                        'visibility_rule': config.get('visibility_rule', 'always_show')
                    }
                    break  # We only process the first configuration
            else:
                if not isinstance(value, dict):
                    raise serializers.ValidationError(f"Configuration for {key} must be a dictionary")
                    
                result = {
                    'header': value.get('header', ''),
                    'icon': value.get('icon', ''),
                    'color': value.get('color', ''),
                    'questions': value.get('questions', []),
                    'function_ref_id': key,
                    'menu_type': None,
                    'is_quick_menu': value.get('is_quick_menu', False),
                    'visibility_rule': value.get('visibility_rule', 'always_show')
                }
            break  # We only process the first top-level key
            
        return result

    def create(self, validated_data):
        return Configuration.objects.create(**validated_data)

    def to_representation(self, instance):
        # Handle single configuration instance
        if isinstance(instance, Configuration):
            if instance.menu_type:
                return {
                    instance.menu_type: {
                        instance.function_ref_id: {
                            'header': instance.header,
                            'icon': instance.icon,
                            'color': instance.color,
                            'questions': instance.questions or [],
                            'is_quick_menu': instance.is_quick_menu,
                            'visibility_rule': instance.visibility_rule
                        }
                    }
                }
            else:
                return {
                    instance.function_ref_id: {
                        'header': instance.header,
                        'icon': instance.icon,
                        'color': instance.color,
                        'questions': instance.questions or [],
                        'is_quick_menu': instance.is_quick_menu,
                        'visibility_rule': instance.visibility_rule
                    }
                }
        
        # Handle queryset of configurations
        result = {}
        menu_configs = {
            'InMenu': {},
            'OutMenu': {}
        }
        
        # Group configurations by menu type
        for config in instance:
            if not isinstance(config, Configuration):
                continue
                
            if config.menu_type == 'InMenu':
                menu_configs['InMenu'][config.function_ref_id] = {
                    'header': config.header,
                    'icon': config.icon,
                    'color': config.color,
                    'questions': config.questions or [],
                    'is_quick_menu': config.is_quick_menu,
                    'visibility_rule': config.visibility_rule
                }
            elif config.menu_type == 'OutMenu':
                menu_configs['OutMenu'][config.function_ref_id] = {
                    'header': config.header,
                    'icon': config.icon,
                    'color': config.color,
                    'questions': config.questions or [],
                    'is_quick_menu': config.is_quick_menu,
                    'visibility_rule': config.visibility_rule
                }
            else:
                # Add as direct function configuration
                result[config.function_ref_id] = {
                    'header': config.header,
                    'icon': config.icon,
                    'color': config.color,
                    'questions': config.questions or [],
                    'is_quick_menu': config.is_quick_menu,
                    'visibility_rule': config.visibility_rule
                }
        
        # Add menu configurations to result if they have items
        for menu_type, functions in menu_configs.items():
            if functions:  # Only add if there are functions in this menu
                result[menu_type] = functions
        
        return result

    def validate(self, data):
        return data 


class AppSettingsSerializer(serializers.ModelSerializer):
    class Meta:
        model = AppSettings
        fields = [
            'id', 'smtp_enabled', 'smtp_host', 'smtp_port', 'smtp_use_tls', 'smtp_use_ssl',
            'smtp_username', 'smtp_password', 'smtp_from_email', 'smtp_from_name',
            'send_welcome_email_on_creation', 'temp_password_length', 'temp_password_expires_hours',
            'force_password_change_on_temp_password',
            'created_at', 'updated_at'
        ]
        read_only_fields = ['id', 'created_at', 'updated_at']
        extra_kwargs = {
            'smtp_password': {'write_only': True}  # Don't return password in GET requests
        }
    
    def validate(self, data):
        # If SMTP is enabled, validate required fields
        if data.get('smtp_enabled', False):
            required_fields = ['smtp_host', 'smtp_username', 'smtp_password', 'smtp_from_email']
            for field in required_fields:
                if not data.get(field):
                    raise serializers.ValidationError(f"{field.replace('_', ' ').title()} is required when SMTP is enabled")
        return data


class ConfigurationTranslationSerializer(serializers.ModelSerializer):
    class Meta:
        model = ConfigurationTranslation
        fields = ['id', 'translation_type', 'language', 'reference_id', 'original_text', 'translated_text', 'created_at', 'updated_at']
        read_only_fields = ['id', 'created_at', 'updated_at']
    
    def validate(self, data):
        # Ensure reference_id is provided
        if not data.get('reference_id'):
            raise serializers.ValidationError("reference_id is required")
        
        # Ensure translation_type and language combination with reference_id is unique
        translation_type = data.get('translation_type')
        language = data.get('language')
        reference_id = data.get('reference_id')
        
        if self.instance:
            # For updates, exclude current instance
            existing = ConfigurationTranslation.objects.filter(
                translation_type=translation_type,
                language=language,
                reference_id=reference_id
            ).exclude(id=self.instance.id)
        else:
            # For creates, check all
            existing = ConfigurationTranslation.objects.filter(
                translation_type=translation_type,
                language=language,
                reference_id=reference_id
            )
        
        if existing.exists():
            raise serializers.ValidationError(
                f"A translation already exists for {translation_type} - {language} - {reference_id}"
            )
        
        return data 