from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import serializers
from django.utils import timezone
from django.contrib.auth import authenticate
from apps.users.serializers.user import UserSerializer
from apps.core.permissions.permissions import get_permissions
from apps.core.permissions.role_permission import get_role_based_permissions, merge_permissions


class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)

        # Add custom claims
        token['user_id'] = str(user.id)
        token['email'] = user.email
        token['name'] = user.name
        token['role'] = user.role
        
        if user.is_superuser:
            base_permissions = get_permissions()
        else:
            base_permissions = get_role_based_permissions(user.role)
            
            if user.permissions:
                base_permissions = merge_permissions(base_permissions, user.permissions)
        
        token['permissions'] = base_permissions
        token['is_staff'] = user.is_staff
        token['is_superuser'] = user.is_superuser
        
        return token


class EmailTokenObtainPairSerializer(CustomTokenObtainPairSerializer):
    """Login with email and password"""
    email = serializers.EmailField(required=True)
    password = serializers.CharField(write_only=True, required=True)
    
    def validate(self, attrs):
        email = attrs.get("email")
        password = attrs.get("password")
        
        # Basic validation
        errors = []
        
        if not email:
            errors.append({
                "field": "email",
                "issue": "validation_error",
                "description": "This field may not be blank.",
                "code": "1002"
            })
        
        if not password:
            errors.append({
                "field": "password", 
                "issue": "validation_error",
                "description": "This field may not be blank.",
                "code": "1002"
            })
        
        if errors:
            raise serializers.ValidationError({
                "success": False,
                "error": {
                    "code": "1002",
                    "details": errors
                },
                "message": "Validation error",
                "timestamp": timezone.now().strftime("%d-%m-%Y %H:%M:%S")
            })
        
        # Authenticate user
        user = authenticate(
            request=self.context.get('request'), 
            email=email,
            password=password
        )

        if not user:
            raise serializers.ValidationError({
                "success": False,
                "error": {
                    "code": "1002",
                    "details": [{
                        "field": "email",
                        "issue": "validation_error",
                        "description": "Invalid email or password",
                        "code": "1002"
                    }]
                },
                "message": "Invalid credentials",
                "timestamp": timezone.now().strftime("%d-%m-%Y %H:%M:%S")
            })

        # Check if user is active
        if not user.is_active:
            raise serializers.ValidationError({
                "success": False,
                "error": {
                    "code": "1003",
                    "details": [{
                        "field": "email",
                        "issue": "account_inactive",
                        "description": "Account is not active",
                        "code": "1003"
                    }]
                },
                "message": "Account is not active",
                "timestamp": timezone.now().strftime("%d-%m-%Y %H:%M:%S")
            })

        # Check if email is verified
        if not user.is_email_verified:
            raise serializers.ValidationError({
                "success": False,
                "error": {
                    "code": "1004",
                    "details": [{
                        "field": "email",
                        "issue": "email_not_verified",
                        "description": "Email is not verified",
                        "code": "1004"
                    }]
                },
                "message": "Email is not verified",
                "timestamp": timezone.now().strftime("%d-%m-%Y %H:%M:%S")
            })

        # Generate tokens
        refresh = self.get_token(user)
        
        # Serialize user data
        user_data = UserSerializer(user, context=self.context).data
        
        return {
            'success': True,
            'message': f'Welcome back, {user.name}!', 
            'data': {
                'refresh': str(refresh),
                'access': str(refresh.access_token),
                'user': user_data,
            },
            'timestamp': timezone.now().strftime("%d-%m-%Y %H:%M:%S")          
        }