from rest_framework import serializers
from django.contrib.auth import authenticate
from django.contrib.auth.tokens import default_token_generator
from django.utils.http import urlsafe_base64_encode
from django.utils.encoding import force_bytes
from django.core.mail import send_mail
from django.conf import settings
from apps.companies.models import Company, CompanyUser
from apps.apps_.models import App, APIKey


class CompanySignupSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    company_name = serializers.CharField(write_only=True)

    class Meta:
        model = CompanyUser
        fields = ["id", "username", "email", "password", "company_name"]

    def create(self, validated_data):
        company_name = validated_data.pop("company_name")
        password = validated_data.pop("password")

        # Create Company
        company = Company.objects.create(name=company_name)

        # Create CompanyUser (admin)
        user = CompanyUser.objects.create(
            **validated_data,
            company=company,
            is_staff=True
        )
        user.set_password(password)
        user.save()

        return user


class UserProfileSerializer(serializers.ModelSerializer):
    """Serializer for viewing and editing user profile"""
    
    class Meta:
        model = CompanyUser
        fields = [
            "id", "username", "email", "first_name", "last_name", 
            "phone_number", "date_joined", "last_login"
        ]
        read_only_fields = ["id", "date_joined", "last_login"]

    def validate_email(self, value):
        user = self.context['request'].user
        if CompanyUser.objects.exclude(pk=user.pk).filter(email=value).exists():
            raise serializers.ValidationError("This email address is already in use.")
        return value

    def validate_username(self, value):
        user = self.context['request'].user
        if CompanyUser.objects.exclude(pk=user.pk).filter(username=value).exists():
            raise serializers.ValidationError("This username is already taken.")
        return value


class PasswordResetRequestSerializer(serializers.Serializer):
    """Serializer for requesting password reset"""
    email = serializers.EmailField()

    def validate_email(self, value):
        try:
            user = CompanyUser.objects.get(email=value)
            self.context['user'] = user
        except CompanyUser.DoesNotExist:
            # Don't reveal if email exists or not for security
            pass
        return value

    def save(self):
        user = self.context.get('user')
        if user:
            # Generate password reset token
            token = default_token_generator.make_token(user)
            uid = urlsafe_base64_encode(force_bytes(user.pk))
            
            # Create reset URL (adjust based on your frontend URL structure)
            reset_url = f"{settings.FRONTEND_URL}/reset-password/{uid}/{token}/"
            
            # Send email
            subject = "Password Reset Request"
            message = f"""
            Hi {user.get_full_name() or user.username},
            
            You requested a password reset for your account. Click the link below to reset your password:
            
            {reset_url}
            
            If you didn't request this reset, please ignore this email.
            
            This link will expire in 24 hours.
            
            Best regards,
            Your Team
            """
            
            send_mail(
                subject,
                message,
                settings.DEFAULT_FROM_EMAIL,
                [user.email],
                fail_silently=False,
            )


class PasswordResetConfirmSerializer(serializers.Serializer):
    """Serializer for confirming password reset"""
    new_password = serializers.CharField(min_length=8, write_only=True)
    confirm_password = serializers.CharField(write_only=True)
    
    def validate(self, attrs):
        if attrs['new_password'] != attrs['confirm_password']:
            raise serializers.ValidationError("Passwords do not match.")
        return attrs


class ChangePasswordSerializer(serializers.Serializer):
    """Serializer for changing password while logged in"""
    current_password = serializers.CharField(write_only=True)
    new_password = serializers.CharField(min_length=8, write_only=True)
    confirm_password = serializers.CharField(write_only=True)

    def validate_current_password(self, value):
        user = self.context['request'].user
        if not user.check_password(value):
            raise serializers.ValidationError("Current password is incorrect.")
        return value

    def validate(self, attrs):
        if attrs['new_password'] != attrs['confirm_password']:
            raise serializers.ValidationError("New passwords do not match.")
        return attrs

    def save(self):
        user = self.context['request'].user
        user.set_password(self.validated_data['new_password'])
        user.save()
        return user


class APIKeySerializer(serializers.ModelSerializer):
    class Meta:
        model = APIKey
        fields = ["id", "key", "created_at", "revoked"]
        read_only_fields = ["id", "key", "created_at"]


class AppSerializer(serializers.ModelSerializer):
    api_keys = serializers.SerializerMethodField()

    class Meta:
        model = App
        fields = ["id", "name", "created_at", "api_keys"]

    def get_api_keys(self, obj):
        qs = obj.keys.filter(revoked=False)
        return APIKeySerializer(qs, many=True).data


class CompanyDetailSerializer(serializers.ModelSerializer):
    apps = AppSerializer(many=True, read_only=True)

    class Meta:
        model = Company
        fields = ["id", "name", "plan", "created_at", "apps"]
        read_only_fields = ["id", "created_at", "apps"]