from rest_framework import serializers
from django.utils.html import strip_tags, escape
from django.core.exceptions import ValidationError
import re
from .models import ContactSubmission


class ContactSubmissionSerializer(serializers.ModelSerializer):
    """
    Serializer for ContactSubmission model.
    Handles both creation and retrieval of contact form submissions.
    """
    
    # Computed fields
    full_name = serializers.ReadOnlyField()
    is_high_priority = serializers.ReadOnlyField()
    is_enterprise_client = serializers.ReadOnlyField()
    industry_display = serializers.SerializerMethodField()
    project_type_display = serializers.SerializerMethodField()
    budget_display = serializers.SerializerMethodField()
    
    class Meta:
        model = ContactSubmission
        fields = [
            'id',
            'first_name',
            'last_name',
            'full_name',
            'email',
            'phone',
            'company',
            'job_title',
            'industry',
            'industry_display',
            'company_size',
            'project_type',
            'project_type_display',
            'timeline',
            'budget',
            'budget_display',
            'message',
            'newsletter_subscription',
            'privacy_consent',
            'status',
            'priority',
            'is_high_priority',
            'is_enterprise_client',
            'created_at',
            'updated_at',
            'admin_notes',
            'assigned_to',
        ]
        read_only_fields = [
            'id',
            'status',
            'priority',
            'created_at',
            'updated_at',
            'admin_notes',
            'assigned_to',
        ]
    
    def get_industry_display(self, obj):
        return obj.get_industry_display()
    
    def get_project_type_display(self, obj):
        return obj.get_project_type_display()
    
    def get_budget_display(self, obj):
        return obj.get_budget_display()
    
    def validate_email(self, value):
        """
        Custom email validation to ensure it's a business email.
        """
        if value and not any(domain in value.lower() for domain in ['@gmail.com', '@yahoo.com', '@hotmail.com']):
            return value
        # Allow personal emails but log them
        return value
    
    def validate_privacy_consent(self, value):
        """
        Ensure privacy consent is given.
        """
        if not value:
            raise serializers.ValidationError("Privacy consent is required to submit the form.")
        return value
    
    def validate(self, attrs):
        """
        Cross-field validation.
        """
        # Ensure required fields are present
        required_fields = ['first_name', 'last_name', 'email', 'company', 'job_title', 'message']
        for field in required_fields:
            if not attrs.get(field):
                raise serializers.ValidationError(f"{field.replace('_', ' ').title()} is required.")
        
        # Validate enterprise client indicators
        if attrs.get('company_size') in ['201-1000', '1000+'] and attrs.get('budget') in ['under-50k', '50k-100k']:
            # This might be a mismatch, but we'll allow it and flag for review
            pass
        
        return attrs


class ContactSubmissionCreateSerializer(serializers.ModelSerializer):
    """
    Simplified serializer for creating contact submissions.
    Only includes fields that should be provided by the frontend.
    """
    
    class Meta:
        model = ContactSubmission
        fields = [
            'first_name',
            'last_name',
            'email',
            'phone',
            'company',
            'job_title',
            'industry',
            'company_size',
            'project_type',
            'timeline',
            'budget',
            'message',
            'newsletter_subscription',
            'privacy_consent',
        ]
    
    def _sanitize_text_field(self, value):
        """
        Sanitize text fields by detecting and rejecting HTML/script tags.
        Returns cleaned text or raises ValidationError if dangerous content is detected.
        """
        if not value:
            return value
        
        # Check for script tags and other dangerous HTML patterns
        dangerous_patterns = [
            (r'<script[^>]*>.*?</script>', 'Script tags are not allowed'),
            (r'<iframe[^>]*>.*?</iframe>', 'Iframe tags are not allowed'),
            (r'javascript:', 'JavaScript protocol is not allowed'),
            (r'on\w+\s*=', 'Event handlers are not allowed'),
            (r'<svg[^>]*onload', 'SVG onload handlers are not allowed'),
            (r'<img[^>]*onerror', 'Image onerror handlers are not allowed'),
            (r'<[^>]+>', 'HTML tags are not allowed'),  # Catch any remaining HTML tags
        ]
        
        value_lower = value.lower()
        for pattern, message in dangerous_patterns:
            if re.search(pattern, value_lower, re.IGNORECASE | re.DOTALL):
                raise serializers.ValidationError(
                    f"Invalid input detected: {message}. Please remove HTML tags and scripts."
                )
        
        # Strip any remaining HTML tags (defense in depth)
        cleaned = strip_tags(value)
        # Remove any remaining script-like content
        cleaned = re.sub(r'javascript:', '', cleaned, flags=re.IGNORECASE)
        
        return cleaned.strip()
    
    def validate_first_name(self, value):
        """Sanitize first name field."""
        return self._sanitize_text_field(value)
    
    def validate_last_name(self, value):
        """Sanitize last name field."""
        return self._sanitize_text_field(value)
    
    def validate_company(self, value):
        """Sanitize company field."""
        return self._sanitize_text_field(value)
    
    def validate_job_title(self, value):
        """Sanitize job title field."""
        return self._sanitize_text_field(value)
    
    def validate_message(self, value):
        """Sanitize message field."""
        return self._sanitize_text_field(value)
    
    def validate_phone(self, value):
        """Sanitize phone field - only allow alphanumeric, spaces, dashes, parentheses, and plus."""
        if not value:
            return value
        
        # Remove HTML tags
        cleaned = strip_tags(value)
        # Only allow phone number characters
        if not re.match(r'^[\d\s\-\+\(\)]+$', cleaned):
            raise serializers.ValidationError("Phone number contains invalid characters.")
        
        return cleaned.strip()
    
    def validate_privacy_consent(self, value):
        """
        Ensure privacy consent is given.
        """
        if not value:
            raise serializers.ValidationError("Privacy consent is required to submit the form.")
        return value
    
    def validate(self, attrs):
        """
        Cross-field validation for creation.
        """
        # Ensure required fields are present
        required_fields = ['first_name', 'last_name', 'email', 'company', 'job_title', 'message']
        for field in required_fields:
            if not attrs.get(field):
                raise serializers.ValidationError(f"{field.replace('_', ' ').title()} is required.")
        
        return attrs


class ContactSubmissionListSerializer(serializers.ModelSerializer):
    """
    Simplified serializer for listing contact submissions.
    Used in admin views and API listings.
    """
    
    full_name = serializers.ReadOnlyField()
    is_high_priority = serializers.ReadOnlyField()
    is_enterprise_client = serializers.ReadOnlyField()
    
    class Meta:
        model = ContactSubmission
        fields = [
            'id',
            'full_name',
            'email',
            'company',
            'job_title',
            'project_type',
            'status',
            'priority',
            'is_high_priority',
            'is_enterprise_client',
            'created_at',
        ]


class ContactSubmissionUpdateSerializer(serializers.ModelSerializer):
    """
    Serializer for updating contact submissions (admin use).
    """
    
    class Meta:
        model = ContactSubmission
        fields = [
            'status',
            'priority',
            'admin_notes',
            'assigned_to',
        ]
    
    def validate_status(self, value):
        """
        Validate status transitions.
        """
        # Add business logic for status transitions if needed
        return value
