from django.contrib.auth import get_user_model
from rest_framework import serializers
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework.exceptions import AuthenticationFailed

User = get_user_model()

class SignUpSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, min_length=8)

    class Meta:
        model = User
        fields = ("username", "email", "password", "role", "phone")

    def create(self, validated_data):
        user = User.objects.create_user(
            username=validated_data['username'],
            email=validated_data.get('email', ''),
            password=validated_data['password'],
            role=validated_data.get('role', 'CUSTOMER'),
            phone=validated_data.get('phone', '')
        )
        return user


class RoleTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        # Add custom claims to the JWT token
        token['role'] = user.role
        token['username'] = user.username
        return token

    def validate(self, attrs):
        # Support Email Login: If username looks like email, find the actual username
        username_input = attrs.get("username")
        if username_input and '@' in username_input:
            user_obj = User.objects.filter(email=username_input).first()
            if user_obj:
                attrs['username'] = user_obj.username

        # Authenticate the user manually to obtain the user instance and create session
        from django.contrib.auth import authenticate
        user = authenticate(username=attrs.get("username"), password=attrs.get("password"))
        if not user:
            raise AuthenticationFailed(detail="No active account found with the given credentials")
        self.user = user

        # Check if role is provided in request
        requested_role = self.initial_data.get("role")
        if requested_role:
             # Case-insensitive comparison
             if self.user.role.upper() != requested_role.upper():
                  raise AuthenticationFailed(detail=f"User is not a {requested_role}")
        
        # Create session
        request = self.context.get("request")
        from users.models import create_user_session
        session = create_user_session(self.user, request)

        # Generate refresh and access tokens
        refresh = self.get_token(self.user)
        refresh['session_key'] = str(session.session_key)
        refresh.access_token['session_key'] = str(session.session_key)
        
        data = {
            "refresh": str(refresh),
            "access": str(refresh.access_token)
        }
        
        # Add extra data to response
        data["role"] = self.user.role
        data["user_id"] = self.user.id
        data["username"] = self.user.username
        
        from rest_framework_simplejwt.settings import api_settings
        from django.contrib.auth.models import update_last_login
        if api_settings.UPDATE_LAST_LOGIN:
            update_last_login(None, self.user)
            
        return data