# -*- coding: utf-8 -*-
"""
Accounts Serializers Module

This module contains serializer classes for the accounts app, providing
JSON serialization and deserialization for API endpoints and data exchange.

Serializers:
    - UserSerializer: Basic user data serialization
    - UserDetailSerializer: Detailed user information
    - UserCreateSerializer: User creation via API
    - UserUpdateSerializer: User profile updates
    - UserListSerializer: User list with minimal data
    - ProfileSerializer: User profile management
    - PasswordChangeSerializer: Password updates
    - BulkUserActionSerializer: Bulk operations

Features:
    - Field validation and sanitization
    - Custom field serialization
    - Nested serialization support
    - Permission-based field filtering
    - API versioning support
    - Error handling and messages

Usage:
    from apps.accounts.serializers import UserSerializer, ProfileSerializer
    
    # Serialize user data
    serializer = UserSerializer(user)
    data = serializer.data
    
    # Create user via API
    serializer = UserCreateSerializer(data=request.data)
    if serializer.is_valid():
        user = serializer.save()

Security:
    - Sensitive field filtering
    - Permission-based access
    - Input validation
    - Data sanitization
"""

from django.utils import timezone
from rest_framework import serializers
from django.contrib.auth import authenticate
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ValidationError as DjangoValidationError

from apps.accounts.models import User


class UserSerializer(serializers.ModelSerializer):
    """
    Basic user serializer for general use.
    
    Provides essential user information without sensitive data.
    Used for user lists, references, and basic operations.
    """
    
    full_name = serializers.CharField(source='get_full_name', read_only=True)
    avatar_url = serializers.SerializerMethodField()
    is_online = serializers.SerializerMethodField()
    
    class Meta:
        model = User
        fields = [
            'id', 'email', 'first_name', 'last_name', 'full_name',
            'avatar_url', 'is_active', 'is_online', 'date_joined',
            'last_login', 'timezone', 'language'
        ]
        read_only_fields = ['id', 'date_joined', 'last_login']
    
    def get_avatar_url(self, obj):
        """Get user avatar URL."""
        if obj.avatar:
            request = self.context.get('request')
            if request:
                return request.build_absolute_uri(obj.avatar.url)
            return obj.avatar.url
        return None
    
    def get_is_online(self, obj):
        """Check if user is currently online."""
        if obj.last_activity:
            return (timezone.now() - obj.last_activity).seconds < 300  # 5 minutes
        return False


class UserDetailSerializer(UserSerializer):
    """
    Detailed user serializer with extended information.
    
    Includes additional fields for detailed user views
    and profile management.
    """
    
    role_display = serializers.CharField(source='get_role_display', read_only=True)
    permissions = serializers.SerializerMethodField()
    activity_count = serializers.SerializerMethodField()
    
    class Meta(UserSerializer.Meta):
        fields = UserSerializer.Meta.fields + [
            'phone', 'bio', 'role', 'role_display', 'permissions',
            'activity_count', 'email_verified', 'two_factor_enabled',
            'last_activity', 'created_at', 'updated_at'
        ]
    
    def get_permissions(self, obj):
        """Get user permissions."""
        return list(obj.get_all_permissions())
    
    def get_activity_count(self, obj):
        """Get user activity count."""
        return obj.activities.count() if hasattr(obj, 'activities') else 0


class UserCreateSerializer(serializers.ModelSerializer):
    """
    Serializer for creating new users via API.
    
    Handles user registration with validation and
    automatic username generation from email.
    """
    
    password = serializers.CharField(
        write_only=True,
        style={'input_type': 'password'},
        help_text=_('Password must be at least 8 characters long.')
    )
    password_confirm = serializers.CharField(
        write_only=True,
        style={'input_type': 'password'},
        help_text=_('Confirm your password.')
    )
    
    class Meta:
        model = User
        fields = [
            'email', 'first_name', 'last_name', 'phone',
            'password', 'password_confirm', 'timezone', 'language'
        ]
        extra_kwargs = {
            'email': {'required': True},
            'first_name': {'required': True},
            'last_name': {'required': True},
        }
    
    def validate_email(self, value):
        """Validate email uniqueness."""
        if User.objects.filter(email=value).exists():
            raise serializers.ValidationError(
                _('A user with this email already exists.')
            )
        return value
    
    def validate_password(self, value):
        """Validate password strength."""
        try:
            validate_password(value)
        except DjangoValidationError as e:
            raise serializers.ValidationError(e.messages)
        return value
    
    def validate(self, attrs):
        """Validate password confirmation."""
        if attrs['password'] != attrs['password_confirm']:
            raise serializers.ValidationError({
                'password_confirm': _('Passwords do not match.')
            })
        return attrs
    
    def create(self, validated_data):
        """Create user with validated data."""
        validated_data.pop('password_confirm')
        password = validated_data.pop('password')
        
        user = User.objects.create_user(
            username=validated_data['email'],
            password=password,
            **validated_data
        )
        return user


class UserUpdateSerializer(serializers.ModelSerializer):
    """
    Serializer for updating user profiles.
    
    Allows users to update their profile information
    without modifying sensitive fields.
    """
    
    class Meta:
        model = User
        fields = [
            'first_name', 'last_name', 'phone', 'bio',
            'timezone', 'language', 'avatar'
        ]
    
    def validate_avatar(self, value):
        """Validate avatar file."""
        if value:
            # Check file size (max 5MB)
            if value.size > 5 * 1024 * 1024:
                raise serializers.ValidationError(
                    _('Avatar file size cannot exceed 5MB.')
                )
            
            # Check file type
            allowed_types = ['image/jpeg', 'image/png', 'image/gif']
            if value.content_type not in allowed_types:
                raise serializers.ValidationError(
                    _('Avatar must be a JPEG, PNG, or GIF image.')
                )
        
        return value


class UserListSerializer(serializers.ModelSerializer):
    """
    Minimal user serializer for lists and references.
    
    Provides only essential information for performance
    in list views and user references.
    """
    
    full_name = serializers.CharField(source='get_full_name', read_only=True)
    avatar_url = serializers.SerializerMethodField()
    
    class Meta:
        model = User
        fields = ['id', 'email', 'full_name', 'avatar_url', 'is_active']
    
    def get_avatar_url(self, obj):
        """Get user avatar URL."""
        if obj.avatar:
            request = self.context.get('request')
            if request:
                return request.build_absolute_uri(obj.avatar.url)
            return obj.avatar.url
        return None


class PasswordChangeSerializer(serializers.Serializer):
    """
    Serializer for password change operations.
    
    Handles password updates with current password verification
    and new password validation.
    """
    
    current_password = serializers.CharField(
        write_only=True,
        style={'input_type': 'password'}
    )
    new_password = serializers.CharField(
        write_only=True,
        style={'input_type': 'password'}
    )
    new_password_confirm = serializers.CharField(
        write_only=True,
        style={'input_type': 'password'}
    )
    
    def validate_current_password(self, value):
        """Validate current password."""
        user = self.context['request'].user
        if not user.check_password(value):
            raise serializers.ValidationError(
                _('Current password is incorrect.')
            )
        return value
    
    def validate_new_password(self, value):
        """Validate new password strength."""
        try:
            validate_password(value, self.context['request'].user)
        except DjangoValidationError as e:
            raise serializers.ValidationError(e.messages)
        return value
    
    def validate(self, attrs):
        """Validate password confirmation."""
        if attrs['new_password'] != attrs['new_password_confirm']:
            raise serializers.ValidationError({
                'new_password_confirm': _('New passwords do not match.')
            })
        return attrs
    
    def save(self):
        """Update user password."""
        user = self.context['request'].user
        user.set_password(self.validated_data['new_password'])
        user.save()
        return user


class BulkUserActionSerializer(serializers.Serializer):
    """
    Serializer for bulk user operations.
    
    Handles bulk actions on multiple users with
    validation and permission checks.
    """
    
    ACTION_CHOICES = [
        ('activate', _('Activate Users')),
        ('deactivate', _('Deactivate Users')),
        ('delete', _('Delete Users')),
        ('export', _('Export Users')),
    ]
    
    action = serializers.ChoiceField(choices=ACTION_CHOICES)
    user_ids = serializers.ListField(
        child=serializers.IntegerField(),
        min_length=1
    )
    
    def validate_user_ids(self, value):
        """Validate user IDs exist."""
        existing_ids = User.objects.filter(id__in=value).values_list('id', flat=True)
        missing_ids = set(value) - set(existing_ids)
        
        if missing_ids:
            raise serializers.ValidationError(
                _('Users with IDs {ids} do not exist.').format(
                    ids=', '.join(map(str, missing_ids))
                )
            )
        
        return value
    
    def validate(self, attrs):
        """Validate action permissions."""
        user = self.context['request'].user
        action = attrs['action']
        
        # Check if user has permission for the action
        if action in ['delete', 'activate', 'deactivate']:
            if not user.has_perm('accounts.change_user'):
                raise serializers.ValidationError(
                    _('You do not have permission to perform this action.')
                )
        
        return attrs